0

There are several things about boost.asio compound operations that are not clear from the official documentation and various threads that I have read on the topic.

The Scenario

Two boost::asio::async_write requests A and B are scheduled on a single TCP socket.

Questions

  1. In a single-threaded process, can it happen that A is executed concurrently with B? Namely, intermediate calls to async_write_some of A are mixed with those of B (which essentially renders a corrupted stream)?
  2. If the answer to (1) is Yes, does io_service::strand solve the issue in single-threaded process? Does it assure that all intermediate calls of A complete before B is started?
  3. Does io_service.strand solve the issue of (1) in a multi-threaded process, when more than one thread execute io_service::run()? Does it assure that all intermediate calls of A complete before B is started?
rbk
  • 11
  • 3
  • Documentation is very clear, really. It may look unclear, but this is because of some "unclear topics" in your mind, proactor pattern for example ! Anyway one of the topnotch SO Question/Answer that helps me on my own learning curve is [that one](http://stackoverflow.com/questions/15568100/confused-when-boostasioio-service-run-method-blocks-unblocks?rq=1). – Jean Davy Jun 25 '14 at 14:58
  • This [answer](http://stackoverflow.com/a/7756894/1053968) provides a solution to the scenario by using a queue to serialize multiple `async_write()` operations, and processing the queue with an asynchronous call chain within a [`strand`](http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_service__strand.html), fulfilling both the requirements of `async_write()` and the stream's thread safety. – Tanner Sansbury Jul 18 '14 at 16:59

1 Answers1

2

The documentations states explicitly: "The program must ensure that the stream performs no other write operations (such as async_write, the stream's async_write_some function, or any other composed operations that perform writes) until this operation completes."

So, multiple async_write's must never be called concurrently. In a single-threaded case, one can chain them, calling a subsequent async_write in the completion hanndler of the previous one.

If io_service::run is run in multiple threads, just wrap async_write's completion handler by a strand, and Asio will synchronize all the intermediate internal handlers.

Community
  • 1
  • 1
Igor R.
  • 14,716
  • 2
  • 49
  • 83
  • I believe "calling a subsequent async_write in the completion handler of the previous one" also solves the multithreaded case without having to wrap the handler – kispaljr Jun 24 '14 at 09:59
  • @igor-r is your asnwer 1. Yes 2. No.No 3. No.No ? – rbk Jun 24 '14 at 10:02
  • @rbk Yes, if by saying "can it happen..." you mean "can it happen, if misused...". – Igor R. Jun 24 '14 at 10:17