// Copyright (c) 2005-2007 Hartmut Kaiser (hartmut.kaiser@gmail.com) // // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// namespace saga { namespace impl { /////////////////////////////////////////////////////////////////////////// // handle API object instance data TR1::shared_ptr proxy::register_instance_data ( TR1::shared_ptr o) { { boost::recursive_mutex::scoped_lock lock(instance_data_mtx_); instance_data_ = o; } boost::detail::thread::lock_ops::lock(o->get_mutex()); return o; } void proxy::release_instance_data() { boost::recursive_mutex::scoped_lock lock(instance_data_mtx_); instance_data_.reset(); } TR1::shared_ptr proxy::check_out_instance_data() { TR1::shared_ptr item; { boost::recursive_mutex::scoped_lock lock(instance_data_mtx_); item = instance_data_; } if (!item) { SAGA_THROW("instance_data: could not check_out instance_data.", saga::DoesNotExist); } boost::detail::thread::lock_ops::lock( item->get_mutex()); return item; } void proxy::check_in_instance_data() { TR1::shared_ptr item; { boost::recursive_mutex::scoped_lock lock(instance_data_mtx_); item = instance_data_; } if (!item) { SAGA_THROW("instance_data: could not check_in instance_data.", saga::DoesNotExist); } boost::detail::thread::lock_ops::unlock( item->get_mutex()); } /////////////////////////////////////////////////////////////////////////// TR1::shared_ptr proxy::shared_from_this() { typedef saga::impl::object base_type; return TR1::static_pointer_cast( this->base_type::shared_from_this()); } TR1::shared_ptr proxy::shared_from_this() const { typedef saga::impl::object base_type; return TR1::static_pointer_cast( this->base_type::shared_from_this()); } /////////////////////////////////////////////////////////////////////////// bool proxy::get_adaptor(std::string const& ops_cpi, std::string const& op_name, preference_type const& prefs, adaptor_selector::adaptor_info_list_type &no_no_list) { // ask session for a new CPI instance (stored in adaptor_) */ TR1::shared_ptr s (runtime::get_impl (this->get_session ())); v1_0::cpi* cpi = s->get_adaptor(ops_cpi, op_name, prefs, this, no_no_list); if (NULL != cpi) { cpis_.add_new(cpi); return true; } return false; } bool proxy::test_adaptor(cpi_type cpi, std::string const& cpi_name, std::string const& op_name, preference_type const& prefs) { // ask adaptor whether the requested mode is supported for the given // CPI call TR1::shared_ptr s (runtime::get_impl (this->get_session())); return s->test_adaptor(cpi.get(), cpi_name, op_name, prefs); } run_mode proxy::test_adaptor_helper(cpi_type cpi, std::string const& cpi_name, std::string const& call_name, preference_type const& prefs, bool is_sync) { if (is_sync) { if (test_adaptor (cpi, cpi_name, "sync_" + call_name, prefs)) return (Sync_Sync); if (test_adaptor (cpi, cpi_name, "async_" + call_name, prefs)) return (Sync_ASync); } else { if (test_adaptor(cpi, cpi_name, "async_" + call_name, prefs)) return (ASync_ASync); if (test_adaptor(cpi, cpi_name, "sync_" + call_name, prefs)) return (ASync_Sync); } TR1::shared_ptr s (runtime::get_impl (this->get_session())); saga::uuid id (cpi->get_adaptor_info().get_adaptor_id()); SAGA_THROW(std::string("Adaptor '") + s->get_adaptor_name(id) + "' doesn't implement " + cpi_name + "::" + call_name, saga::NoAdaptor); return Unknown; } bool proxy::initcpi(std::string const& cpi_name, preference_type const& prefs /*= preference_type()*/ ) { adaptor_selector::adaptor_info_list_type no_no_list; exception_list exceptions; while (true) { try { // create new CPI instance (remember, this is called from the // inside of the constructor of the API object) mutex_type::scoped_lock lock(cpis_mtx_); run_mode mode = get_adaptor_for_init(cpi_name, prefs, no_no_list); BOOST_ASSERT(!cpis_.empty()); BOOST_ASSERT(Sync_Sync == mode); return true; } catch (saga::exception const& e) { exceptions.add(e); // save this exception // throw, if we don't find anything if (e.get_error() == saga::NoAdaptor) SAGA_THROW(exceptions.get_message(), exceptions.get_error()); } } } run_mode proxy::get_adaptor_helper(std::string const& cpi_name, std::string const& call_name, preference_type const& prefs, bool is_sync, adaptor_selector::adaptor_info_list_type &no_no_list) { // find a new adaptor matching the requirements if (is_sync) { if (get_adaptor (cpi_name, "sync_" + call_name, prefs, no_no_list)) { return (Sync_Sync); } if (get_adaptor (cpi_name, "async_" + call_name, prefs, no_no_list)) { return (Sync_ASync); } } else { if (get_adaptor (cpi_name, "async_" + call_name, prefs, no_no_list)) { return (ASync_ASync); } if (get_adaptor (cpi_name, "sync_" + call_name, prefs, no_no_list)) { return (ASync_Sync); } } SAGA_THROW("No (other) adaptor implements " + cpi_name + "::" + call_name, saga::NoAdaptor); return Unknown; } run_mode proxy::get_adaptor_for_init(std::string const& cpi_name, preference_type const& prefs, adaptor_selector::adaptor_info_list_type &no_no_list ) { // find a new adaptor matching the requirements if (get_adaptor(cpi_name, "__init__", prefs, no_no_list)) return (Sync_Sync); SAGA_THROW("No adaptor succeeded in executing constructor for " + cpi_name, saga::NoAdaptor); return Unknown; } run_mode proxy::select_run_mode(std::string const& cpi_name, std::string const& call_name, preference_type const& prefs, bool is_sync, adaptor_selector::adaptor_info_list_type &no_no_list) { // first try all the cpi instances we have loaded already exception_list exceptions; cpi_list::iterator end = cpis_.end(); for (cpi_list::iterator it = cpis_.begin(); it != end; ++it) { v1_0::cpi_info info; try { // retrieve info to be able to store it in no_no_list later info = (*it)->get_adaptor_info(); if (std::find_if (no_no_list.begin(), no_no_list.end(), v1_0::same_cpi(info)) != no_no_list.end()) { continue; // this cpi was checked already } // ask this cpi instance if it is able to handle the request. // throws if not. run_mode mode = test_adaptor_helper(*it, cpi_name, call_name, prefs, is_sync); cpis_.make_current(it); return mode; } catch (saga::exception const& e) { exceptions.add(e); // save this exception // throw, if we don't find anything or if this cpi has the // Fixme flag set if (e.get_error() == saga::NoAdaptorInfo || ((*it)->get_flags() & v1_0::cpi::Fixme)) { SAGA_THROW(exceptions.get_message(), exceptions.get_error()); } no_no_list.push_back(info); // just try the next adaptor } } // then try to instantiate a new instance try { return get_adaptor_helper(cpi_name, call_name, prefs, is_sync, no_no_list); } catch (saga::exception const& e) { exceptions.add(e); SAGA_THROW(exceptions.get_message(), exceptions.get_error()); } return Unknown; } /////////////////////////////////////////////////////////////////////////////// }} // namespace saga::impl