|
Boost Users : |
Subject: Re: [Boost-users] [asio] user defined composed operations and strands
From: Marat Abrarov (abrarov_at_[hidden])
Date: 2011-08-09 16:08:45
Hi, Tacheon.
> If async_write_data is called and io_service::run is called from multiple threads, strands are should
> be necessary to avoid raced.
> The question is: How do I support handlers wrapped in a strand and how do I get this strand forwarded
> to async_read?
> As far as I understand this should be somehow possible by using asio_handler_invoke but the
> documentation is a bit too fuzzy on the topic for me to understand.
There is no such info in Asio docs.
You may look at asio-samples (http://sourceforge.net/projects/asio-samples). There is ma::context_wrapped_handler class
(and ma::make_context_wrapped_handler helper function) that makes such a wrapper for intermediate handler. But you
shouldn't use
> typedef boost::function<void (error_t const &)> completion_handler_t;
because it hides asio_hanlder_invoke defined for the original (user supplied) handler.
You may write something like this:
class io_port
{
public:
//Ctors and so on...
template<typename Handler>
void async_read_data
( raw_buffer_t & buffer
, Handler const & handler)
{
//uses a composed operation itself...
boost::asio::async_read
( socket
, boost::asio::buffer(header)
, ma::make_context_wrapped_handler(handler,
boost::bind
( &io_port::handle_header_received<Handler>
, this
, boost::ref(buffer)
, handler
, boost::asio::placeholders::error)));
}
//first intermediate handler
template<typename Handler>
void handle_header_received
( raw_buffer_t & data
, Handler const & handler
, boost::system::error_code const & error
{
if(error)
{
handler(error_t(error));
}
else
{
prepare_buffer(data, header.perparation_data()); //pseudo-code
//uses a composed operation itself...
boost::asio::async_read
( socket
, boost::asio::buffer(data)
, ma::make_context_wrapped_handler(handler,
boost::bind(&io_port::handle_data_received<Handler>
, this
, boost::ref(buffer)
, handler
, boost::asio::placeholders::error) );
}
}
//second intermediate handler
template<typename Handler>
void handle_data_received
( raw_buffer_t & data
, Handler const & handler
, boost::system::error_code const & error )
{
if(error)
{
handler(error_t(error));
}
else
{
handler(error_t());
}
}
};
Also, it will be very helpful to read Asio sources: /boost/asio/impl/read.hpp: 339 and 145 (Boost 1.47).
May be it' will be better to implement io_port class similar to boost::asio::detail::read_op.
Regards,
Marat Abrarov.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net