Re: [Boost-users] [Asio] Socket Read/Write Thread-Safety (Timothy Liang)
The 'boost::asio::async_read(...)' and 'boost::asio::async_write(...)' functions might call async_read_some and async_write_some concurrently in some scenarios, as they do not synchronize accesses to the stream object that I'm passing to them as a reference. A look in their implementations confirms this: if the stream's async_read_some or async_write_some didn't satisfy the completion condition, it tries again, using the same reference to the stream object. With multiple threads calling io_service::run_one(), the result can be one thread calling async_read_some while another is calling async_write_some at the same time. This seems to prevent me from using async_read and async_write at all, so I'm wondering if the stream has some undocumented thread-safety guarantees, or if there's a proper way to achieve the same effect.
RTFM. Really, RTFM. Use boost::asio::io_service::strand and don't worry about synchronization. http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/overview/core/stran ds.html You can use async_read and async_write simultaneously (but note "Thread Safety" for used asio class) with strands easily. Yes, with multiple threads running boost::asio::io_service::run on the same boost::asio::io_service object. What amazing laziness in reading asio docs :) - all of the latest questions about Boost.Asio have respective answers in documentation. Marat Abrarov.
RTFM. Really, RTFM. Use boost::asio::io_service::strand and don't worry about synchronization.
http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/overview/core/stran...
You can use async_read and async_write simultaneously (but note "Thread Safety" for used asio class) with strands easily. Yes, with multiple threads running boost::asio::io_service::run on the same boost::asio::io_service object.
What amazing laziness in reading asio docs :) - all of the latest questions about Boost.Asio have respective answers in documentation.
Marat Abrarov.
Thanks for your reply. I've read the docs already, and didn't find a good explanation. After a couple of days of searching, I got frustrated and asked in the IRC channel. Still without an answer, I looked through the docs again and then took the time to subscribe to this mailing list and type up a detailed and concise question. And then waited patiently for the moderators to review my mail for approval. I think that page could present a better example. I did come across it, but it used the term 'intermediate handler', which I thought was referring to the completion-condition handler. It also didn't say that I had to directly pass my wrapped handler to the composed operations as the completion handler, without encapsulating it in another function object, which I was doing since I thought that the wrapped handler type only served as a functor. I wasn't aware that there was a hooking mechanism for all handlers called by the io_service that used ADL to find custom invocation code. The example on the page makes perfect sense now that I know about it, but I couldn't for the life of me understand it before.
participants (2)
-
Marat Abrarov
-
Timothy Liang