5

Suppose when calling io_service::run(), there are multiple async_read operations scheduled (There may be other operations in between them). What happens when an asynchronous operation like async_write is scheduled in the ReadHandler-function?

void handler(const boost::system::error_code& error, std::size_t bytes) {
    async_write(sock, boost::asio::buffer(wbuf), whandler);
}

That is, when will the async_write be invoked? I would expect the order of execution to be:

1) async_read //1
2) async_write
3) async_read //2
4) async_write

Is this order of execution guaranteed?

Marius Herzog
  • 589
  • 3
  • 18

3 Answers3

4

No, it's not guaranteed. For example, if the first handler is invoked and wants to write, what if the second buffer is not yet available to read? Of course the write should come first. But what if the write is not possible by the time the second buffer is ready to read? Then of course the second read should occur before the first write.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
3

You are misusing the boost::asio interface.

There may not be more than one pending read operations on a single socket.

Quote from the boost::asio::async_read docs:

This operation is implemented in terms of zero or more calls to the stream's async_read_some function, and is known as a composed operation. The program must ensure that the stream performs no other read operations (such as async_read, the stream's async_read_some function, or any other composed operations that perform reads) until this operation completes.

Stephan Dollberg
  • 32,985
  • 16
  • 81
  • 107
  • I don't use multiple async_reads, the example was just quickly made up. One of the async_reads could be an other async operation. I see if I can edit it. – Marius Herzog Sep 08 '14 at 13:35
  • @MariusHerzog That would be good to see what you really mean. – Stephan Dollberg Sep 08 '14 at 13:45
  • I think what I really mean is: When calling run(), there are multiple async_reads scheduled (There can be other operations in between them). When the ReadHandler invokes an async_write, are the async_writes immediately processed after the ReadHandler is finished? – Marius Herzog Sep 08 '14 at 18:15
  • @MariusHerzog Ok, then the other answers answer your question just fine. However, if you always have only a single read/write this shouldn't be a problem as you can control your flow by doing the next read/write from the previous callback. – Stephan Dollberg Sep 08 '14 at 18:32
2

You can force the order of execution using strands

An excellent description is here: Why do I need strand per connection when using boost::asio?

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633