I figured out what my problem was. This was a container going out of
scope and being destroyed. The iterators that still existed in ASIO
were pointing to an invalid container.
---------
Robert Dailey
On Wed, Aug 26, 2009 at 1:09 PM, Robert Dailey
Inside of win_iocp_handle_service.write_operation.do_completion_impl(), there is this block of code (Note I'm using Boost 1.40 Beta):
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. typename ConstBufferSequence::const_iterator iter = handler_op->buffers_.begin(); typename ConstBufferSequence::const_iterator end = handler_op->buffers_.end(); while (iter != end) { boost::asio::const_buffer buffer(*iter); boost::asio::buffer_cast
(buffer); ++iter; } #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) The call to buffers_.begin() is causing the assert. Looks like a container is getting invalidated/corrupted somehow. I have no idea why this is happening. I'm calling io_service::run() from its own worker thread in a continuous loop like so:
for(;;) { boost::this_thread::sleep( boost::posix_time::milliseconds( 20 ) ); m_service.run(); }
The class that is wrapping the io_service and serial_port objects invokes a post at construction (from the main thread), to start off a transparent yet continuous chain of reads over the serial port:
m_service.post( boost::bind( &SerialClient::DoRead, this ) );
After that, externally I call a function that posts a write in a similar way. This write occurs after the above post for the read:
m_service.post( boost::bind( &SerialClient::DoWrite, this, data ) );
When I step through the sequence of events, I see the following happen:
- io_service and serial_port are constructed and initialized - io_service thread is started (But run() has not been called yet) - The DoRead() is posted to the io_service - The DoWrite() is posted to the io_service - io_service.run() is called from the worker thread for the first time - DoRead() is called from io_service::run(), which in turn calls serial_port::async_read_some() - DoWrite() is called from io_service::run(), which in turn calls boost::asio::async_write() on the serial_port - ReadCompleted() is invoked as the callback from the previous serial_port::async_read_some() call. It does NOT call async_read_some again (for testing, I disabled the looped reading). - After ReadCompleted() scope exits, it throws the assert
Not sure what I'm doing wrong. Keep in mind that this whole time the COM port is not connected to anything, but I'm not sure if this will have anything to do with it. I've attached the code just in case you don't mind looking over it.
--------- Robert Dailey