Robert Dailey wrote:
On Tue, Aug 25, 2009 at 6:36 PM, Michael Caisse
mailto:boost@objectmodelingdesigns.com> wrote: Why are you having to poll?
What I'm really asking is: How do you know when to call async_read_some()? Ideally I only want to call into the socket to read information when I get a callback saying that there is actually something in the read buffer to get. A short sequence of what I want to happen:
1. Send a message over the COM port 2. Wait for the device to reply (The device would send a message back) 3. Receive a callback saying that a new message (new data) is available and ready to be read 4. Call async_read() to obtain that data.
Robert - It looks like you might be thinking about the problem in a synchronous manner. Let me suggest a different way to think about the problem. Let us pretend that your messages across the COM port are delimited in some manner (like a standard STX/ETX). You now have some object that invokes an async_read_some for the port and just waits. I wont digress on all the reasons I think async_read_some is the right choice... for now lets just assume that my way works (o; The completion handler for async_read_some will look for the STX and then collect bytes until it finds an ETX. When the completion handler is called it may very well not have an entire message in the buffer. That is fine. It will just start another async_read_some. Eventually a message will be formed. This is a good point to receive your callback saying that a new message is available. Not only available... but here it is. That is the basic idea. When do you call async_read? Right after you open the port. The reads are just going on in the background putting together useful atoms of data and then alerting you that something worthwhile is available to look at. So... you might have some thing like this: (I'm just now making this up for illustration ... not for efficiency and may not even work) 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 ]; } } } else { close_port( error ); } } I hope this helps some. Obviously the example has issues but it might give you another way to think about the problem. Michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com