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()); }
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)); }
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); }
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); }