
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
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.