Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple async_wait from a boost Asio deadline_timer

Is it possible to call async_wait several times on the same boost::asio::deadline_timer?

What I mean to do is something like the following:

t->expires_from_now(delay);
t->async_wait(f1);
t->async_wait(f2);

Does this ensures that the two functions will be called? Does this ensures that the two functions will be called in this order?

If not, any idea how to have f1 and f2 successively called when the timer times out? (I don't care if another handler is executed between the calls to f1 and f2).

Another question: if two timers t1 and t2 are set such that the deadline of t1 is before the deadline of t2, can I be sure that the handler associated to t1 will be called before the handler associated to t2? (in which case for the above code, I would just create a second timer for f2 with a delay slightly larger than the delay set for the first timer).

Thanks

like image 705
sunmat Avatar asked Mar 24 '23 06:03

sunmat


1 Answers

Carefully reading the documentation on http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/basic_deadline_timer/async_wait.html, it states that

For each call to async_wait(), the supplied handler will be called exactly once.

(emphasis mine). That means that in your case, both f1 and f2 will be called once.

To your second question: That depends on 3 conditions:

  1. There might be issues when the expiration times differ only by a short period below the resolution of the system clock (or of the OS'es timing service). The behavior in that case is defined by the timer implementation (but should not be a problem with the default implementation by Boost, see the comments).
  2. The possible concurrency of the two handlers in multithreaded environments. Wrap the two handlers into the same strand to get issues related to concurrency out of the way.
  3. The possibility of cancellation of the timers. When the later timer gets cancelled before the earlier timer expires, (by setting another expiration time), it fires its handlers before the earlier timer does.

Update:
I just now realized that there was a second part in your first question regarding the order in which the handlers get called. The documentations does not say anything about that. You could look it up in the implementation, but that may change.
In the case that you want two functions executed in order, just call the second from the first one. If that second handler should get "appended" to the first one only in certain conditions, either delay the call to async_wait until you know the whole extent of the handler chain, or just make them independent of each other.
The third possibility would be to roll your own, appendable handler. But bear in mind, that handlers get copied into the io_service::run thread, i.e. into the async_wait calls, so the appendable handler will need only a pointer to the real chain of handlers, it will need to take concurrency into account and so on.

like image 169
Arne Mertz Avatar answered Mar 31 '23 12:03

Arne Mertz