response component_namespace::resolve_id( request const& req , error_code& ec ) { // {{{ resolve_id implementation // parameters component_id_type key = req.get_component_type(); // If the requested component type is a derived type, use only its derived // part for the lookup. if (key != components::get_base_type(key)) key = components::get_derived_type(key); std::lock_guard<mutex_type> l(mutex_); factory_table_type::const_iterator it = factories_.find(key) , end = factories_.end(); // REVIEW: Should we differentiate between these two cases? Should we // throw an exception if it->second.empty()? It should be impossible. if (it == end || it->second.empty()) { LAGAS_(info) << (boost::format( "component_namespace::resolve_id, key(%1%), localities(0)") % key); if (&ec != &throws) ec = make_success_code(); return response(component_ns_resolve_id , std::vector<boost::uint32_t>()); } else { std::vector<boost::uint32_t> p; prefixes_type const& prefixes = it->second; prefixes_type::const_iterator pit = prefixes.begin() , pend = prefixes.end(); for (; pit != pend; ++pit) p.push_back(*pit); LAGAS_(info) << (boost::format( "component_namespace::resolve_id, key(%1%), localities(%2%)") % key % prefixes.size()); if (&ec != &throws) ec = make_success_code(); return response(component_ns_resolve_id, p); } } // }}}
response symbol_namespace::statistics_counter( request const& req , error_code& ec ) { // {{{ iterate implementation LAGAS_(info) << "symbol_namespace::statistics_counter"; return response(); }
response component_namespace::unbind( request const& req , error_code& ec ) { // {{{ unbind implementation // parameters std::string key = req.get_name(); std::lock_guard<mutex_type> l(mutex_); component_id_table_type::left_map::iterator it = component_ids_.left.find(key); // REVIEW: Should this be an error? if (it == component_ids_.left.end()) { LAGAS_(info) << (boost::format( "component_namespace::unbind, key(%1%), response(no_success)") % key); if (&ec != &throws) ec = make_success_code(); return response(component_ns_unbind_name, no_success); } // REVIEW: If there are no localities with this type, should we throw // an exception here? factories_.erase(it->second); component_ids_.left.erase(it); LAGAS_(info) << (boost::format( "component_namespace::unbind, key(%1%)") % key); if (&ec != &throws) ec = make_success_code(); return response(component_ns_unbind_name); } // }}}
response symbol_namespace::unbind( request const& req , error_code& ec ) { // {{{ unbind implementation // parameters std::string key = req.get_name(); mutex_type::scoped_lock l(mutex_); gid_table_type::iterator it = gids_.find(key) , end = gids_.end(); if (it == end) { LAGAS_(info) << (boost::format( "symbol_namespace::unbind, key(%1%), response(no_success)") % key); if (&ec != &throws) ec = make_success_code(); return response(symbol_ns_unbind, naming::invalid_gid, no_success); } const naming::gid_type gid = it->second; gids_.erase(it); LAGAS_(info) << (boost::format( "symbol_namespace::unbind, key(%1%), gid(%2%)") % key % gid); if (&ec != &throws) ec = make_success_code(); return response(symbol_ns_unbind, gid); } // }}}
response component_namespace::bind_name( request const& req , error_code& ec ) { // {{{ bind_name implementation // parameters std::string key = req.get_name(); std::unique_lock<mutex_type> l(mutex_); component_id_table_type::left_map::iterator it = component_ids_.left.find(key) , end = component_ids_.left.end(); // If the name is not in the table, register it (this is only done so // we can implement a backwards compatible get_component_id). if (it == end) { if (HPX_UNLIKELY(!util::insert_checked(component_ids_.left.insert( std::make_pair(key, type_counter)), it))) { l.unlock(); HPX_THROWS_IF(ec, lock_error , "component_namespace::bind_name" , "component id table insertion failed due to a locking " "error or memory corruption"); return response(); } // If the insertion succeeded, we need to increment the type // counter. ++type_counter; } LAGAS_(info) << (boost::format( "component_namespace::bind_name, key(%1%), ctype(%2%)") % key % it->second); if (&ec != &throws) ec = make_success_code(); return response(component_ns_bind_name, it->second); } // }}}
// TODO: catch exceptions response symbol_namespace::iterate( request const& req , error_code& ec ) { // {{{ iterate implementation iterate_names_function_type f = req.get_iterate_names_function(); mutex_type::scoped_lock l(mutex_); for (gid_table_type::iterator it = gids_.begin() , end = gids_.end(); it != end; ++it) { f(it->first, it->second); } LAGAS_(info) << "symbol_namespace::iterate"; if (&ec != &throws) ec = make_success_code(); return response(symbol_ns_iterate_names); } // }}}
// TODO: catch exceptions response component_namespace::iterate_types( request const& req , error_code& ec ) { // {{{ iterate implementation iterate_types_function_type f = req.get_iterate_types_function(); std::lock_guard<mutex_type> l(mutex_); for (component_id_table_type::left_map::iterator it = component_ids_.left.begin() , end = component_ids_.left.end(); it != end; ++it) { f(it->first, it->second); } LAGAS_(info) << "component_namespace::iterate_types"; if (&ec != &throws) ec = make_success_code(); return response(component_ns_iterate_types); } // }}}
response symbol_namespace::resolve( request const& req , error_code& ec ) { // {{{ resolve implementation // parameters std::string key = req.get_name(); mutex_type::scoped_lock l(mutex_); gid_table_type::iterator it = gids_.find(key) , end = gids_.end(); if (it == end) { LAGAS_(info) << (boost::format( "symbol_namespace::resolve, key(%1%), response(no_success)") % key); if (&ec != &throws) ec = make_success_code(); return response(symbol_ns_resolve , naming::invalid_gid , no_success); } if (&ec != &throws) ec = make_success_code(); naming::gid_type gid; // Is this entry reference counted? if (naming::get_credit_from_gid(it->second) != 0) { gid = naming::split_credits_for_gid(it->second); LAGAS_(debug) << (boost::format( "symbol_namespace::resolve, split credits for entry, " "key(%1%), entry(%2%), gid(%3%)") % key % it->second % gid); // Credit exhaustion - we need to get more. if (0 == naming::get_credit_from_gid(gid)) { BOOST_ASSERT(1 == naming::get_credit_from_gid(it->second)); naming::get_agas_client().incref(gid, 2 * HPX_INITIAL_GLOBALCREDIT); naming::add_credit_to_gid(gid, HPX_INITIAL_GLOBALCREDIT); naming::add_credit_to_gid(it->second, HPX_INITIAL_GLOBALCREDIT); LAGAS_(debug) << (boost::format( "symbol_namespace::resolve, incremented entry credits, " "key(%1%), entry(%2%), gid(%3%)") % key % it->second % gid); } } else gid = it->second; LAGAS_(info) << (boost::format( "symbol_namespace::resolve, key(%1%), gid(%2%)") % key % gid); return response(symbol_ns_resolve, gid); } // }}}
response component_namespace::bind_prefix( request const& req , error_code& ec ) { // {{{ bind_prefix implementation // parameters std::string key = req.get_name(); boost::uint32_t prefix = req.get_locality_id(); std::unique_lock<mutex_type> l(mutex_); component_id_table_type::left_map::iterator cit = component_ids_.left.find(key) , cend = component_ids_.left.end(); // This is the first request, so we use the type counter, and then // increment it. if (component_ids_.left.find(key) == cend) { if (HPX_UNLIKELY(!util::insert_checked(component_ids_.left.insert( std::make_pair(key, type_counter)), cit))) { l.unlock(); HPX_THROWS_IF(ec, lock_error , "component_namespace::bind_prefix" , "component id table insertion failed due to a locking " "error or memory corruption"); return response(); } // If the insertion succeeded, we need to increment the type // counter. ++type_counter; } factory_table_type::iterator fit = factories_.find(cit->second) , fend = factories_.end(); if (fit != fend) { prefixes_type& prefixes = fit->second; prefixes_type::iterator pit = prefixes.find(prefix); if (pit != prefixes.end()) { // Duplicate type registration for this locality. l.unlock(); HPX_THROWS_IF(ec, duplicate_component_id , "component_namespace::bind_prefix" , boost::str(boost::format( "component id is already registered for the given " "locality, key(%1%), prefix(%2%), ctype(%3%)") % key % prefix % cit->second)); return response(); } fit->second.insert(prefix); // First registration for this locality, we still return no_success to // convey the fact that another locality already registered this // component type. LAGAS_(info) << (boost::format( "component_namespace::bind_prefix, key(%1%), prefix(%2%), " "ctype(%3%), response(no_success)") % key % prefix % cit->second); if (&ec != &throws) ec = make_success_code(); return response(component_ns_bind_prefix , cit->second , no_success); } // Instead of creating a temporary and then inserting it, we insert // an empty set, then put the prefix into said set. This should // prevent a copy, though most compilers should be able to optimize // this without our help. if (HPX_UNLIKELY(!util::insert_checked(factories_.insert( std::make_pair(cit->second, prefixes_type())), fit))) { l.unlock(); HPX_THROWS_IF(ec, lock_error , "component_namespace::bind_prefix" , "factory table insertion failed due to a locking " "error or memory corruption"); return response(); } fit->second.insert(prefix); LAGAS_(info) << (boost::format( "component_namespace::bind_prefix, key(%1%), prefix(%2%), ctype(%3%)") % key % prefix % cit->second); if (&ec != &throws) ec = make_success_code(); return response(component_ns_bind_prefix, cit->second); } // }}}