Esempio n. 1
0
    void parcelport::send_pending_parcels(
        parcelport_connection_ptr client_connection,
        std::vector<parcel> const & parcels,
        std::vector<write_handler_type> const & handlers)
    {
#if defined(HPX_DEBUG)
        // verify the connection points to the right destination
        BOOST_FOREACH(parcel const& p, parcels)
        {
            naming::locality const parcel_locality_id = p.get_destination_locality();
            BOOST_ASSERT(parcel_locality_id == client_connection->destination());
            BOOST_ASSERT(parcel_locality_id.get_address() ==
                client_connection->socket().remote_endpoint().address().to_string());
            BOOST_ASSERT(parcel_locality_id.get_port() ==
                client_connection->socket().remote_endpoint().port());
        }
Esempio n. 2
0
    void parcelport::send_pending_parcels(
        parcelport_connection_ptr client_connection,
        std::vector<parcel> const & parcels,
        std::vector<write_handler_type> const & handlers)
    {
        // store parcels in connection
        // The parcel gets serialized inside set_parcel, no
        // need to keep the original parcel alive after this call returned.
        client_connection->set_parcel(parcels);

        // ... start an asynchronous write operation now.
        client_connection->async_write(
            hpx::parcelset::detail::call_for_each(handlers),
            boost::bind(&parcelport::send_pending_parcels_trampoline, 
                this->shared_from_this(),
                boost::asio::placeholders::error, ::_2, ::_3));
    }
Esempio n. 3
0
    void parcelport::send_parcels_or_reclaim_connection(
        naming::locality const& locality_id, 
        parcelport_connection_ptr const& client_connection)
    {
        typedef pending_parcels_map::iterator iterator;

        std::vector<parcel> parcels;
        std::vector<write_handler_type> handlers;

        {
            lcos::local::spinlock::scoped_lock l(mtx_);
            iterator it = pending_parcels_.find(locality_id);

            if (it != pending_parcels_.end())
            {
                BOOST_ASSERT(it->first == locality_id);
                std::swap(parcels, it->second.first);
                std::swap(handlers, it->second.second);

                if (parcels.empty())
                {
                    // if no parcels are pending re-add the connection to
                    // the cache
                    BOOST_ASSERT(handlers.empty());
                    BOOST_ASSERT(locality_id == client_connection->destination());
                    connection_cache_.reclaim(locality_id, client_connection);
                    return;
                }
            }
            else 
            {
                // Give this connection back to the cache as it's not
                // needed anymore.
                BOOST_ASSERT(locality_id == client_connection->destination());
                connection_cache_.reclaim(locality_id, client_connection);
                return;
            }
        }

        // send parcels if they didn't get sent by another connection
        send_pending_parcels(client_connection, parcels, handlers);
    }
Esempio n. 4
0
    void parcelport::send_pending_parcels_trampoline(
        boost::system::error_code const& ec,
        naming::locality const& locality_id,
        parcelport_connection_ptr client_connection)
    {
        {
            lcos::local::spinlock::scoped_lock l(mtx_);

            // Give this connection back to the cache as it's not  needed anymore.
            BOOST_ASSERT(locality_id == client_connection->destination());
            connection_cache_.reclaim(locality_id, client_connection);

            pending_parcels_map::iterator it = pending_parcels_.find(locality_id);
            if (it == pending_parcels_.end() || it->second.first.empty())
                return;
        }

        // Create a new HPX thread which sends parcels that are still pending.
        hpx::applier::register_thread_nullary(
            HPX_STD_BIND(&parcelport::retry_sending_parcels, 
                this->shared_from_this(), locality_id), "retry_sending_parcels",
                threads::pending, true, threads::thread_priority_critical);
    }