On Tue, Aug 25, 2009 at 9:04 PM, Michael Caisse <boost@objectmodelingdesigns.com> wrote:
Whoops ... forgot to start the read again in the completion handler.
"Fixed" below.


Michael Caisse wrote:



void my_message_maker::read_start()
{
 serial_port.async_read_some( boost::asio::buffer( in_message, MAX_MESSAGE_SIZE ),
                              boost::bind( &my_message_maker::read_done,
                                           this,
                                           boost::asio::placeholders::error,
                                           boost::asio::placeholders::bytes_transferred ) );
}


void my_message_maker::read_done( const boost::system::error_code& error,
                                int bytes_transferred )
{
 if( !error )
 {
    for( int i=0; i < bytes_transferred; ++i )
    {
       if( in_message[ i ] == STX )
       {
          my_message.clear();
       }
       else if( in_message[ i ] == ETX )
       {
          make_callback( my_message );
       }
       else
       {
          my_message += in_message[ i ];
       }
        read_start();
     }

 }
 else
 {
    close_port( error );
 }
}

Ah, i see what you're saying now. I was thinking from a lower level (i.e. that I would not call any read methods until I was notified from the socket/serial port layer that information was ready). It's actually a good idea to take it up to a higher level like this and validate data completion and defragment the buffers.

Would you recommend calling read_start() from its own thread and have it loop indefinitely? I believe this is what you originally suggested. However, I am curious about the issues with calling read_some() and write_some() from separate threads without using any external synchronization techniques (i.e. mutexes). Do I have to synchronize these two calls manually or is it done internally? I'll re-review the documentation, but I did not see anything regarding this earlier.

Thanks for your help.