Boost logo

Boost Users :

Subject: [Boost-users] [asio] user defined composed operations and strands
From: Tacheon (Tacheon_at_[hidden])
Date: 2011-08-09 06:00:07


Hello,

I am trying to implement some new composed operations (like boost::asio::async_read) with asio.
However I am a bit concerned about thread-safety when the run-method of the used io_service object ist called from multiple threads and there are parallel read- and write operations on the same socket.

The composed operations look like this:
class io_port
{
public:
    //Ctors and so on...
    typedef boost::function<void (error_t const &)> completion_handler_t;
   
   void async_read_data
       ( raw_buffer_t & buffer
       , completion_handler_t const & handler)
    {
        //uses a composed operation itself...
        boost::asio::async_read
            ( socket
            , boost::asio::buffer(header)
            , boost::bind
                ( &io_port::handle_header_received
                , this
                , boost::ref(buffer)
                , handler
                , boost::asio::placeholders::error) );
    }
    
    //first intermediate handler
    void handle_header_received
        ( raw_buffer_t & data
        , completion_handler_type 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)
                , boost::bind
                    ( &io_port::handle_data_received
                    , this
                    , boost::ref(buffer)
                    , handler
                    , boost::asio::placeholders::error) );
        }
    }
    
    //second intermediate handler
    void handle_data_received
        ( raw_buffer_t & data
        , completion_handler_type const & handler
        , boost::system::error_code const & error )
    {
        if(error)
        {
            handler(error_t(error));
        }
        else
        {
            handler(error_t());
        }
    }
    
    void async_write_data
        ( raw_buffer_t const & buffer
        , completion_handler_t const & handler)
    { ... } //quite similar to async_read_data
        
};

usage may be either

port.async_read
    ( buffer
    , handler );
    
or

port.async_read
    ( buffer
    , strand.wrap(handler) ); //how to forward this to asio::async_read?

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.

-- 
Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de

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