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);
    }
} // }}}
Ejemplo n.º 2
0
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);
} // }}}
Ejemplo n.º 4
0
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);
} // }}}
Ejemplo n.º 6
0
// 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);
} // }}}
Ejemplo n.º 8
0
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);
} // }}}