
Hi Dick, --- BRIDGES Dick <Dick.Bridges@us.thalesgroup.com> wrote:
I'm performing an async_wait() on a deadline_timer. Based upon some independent event (e.g., a keystroke) I want to [re]set the timer and, if it was expired, 'fire' an event indicating that the system has changed state from not_running to running.
Maybe I'm missing something obvious, but it seems that deadline_timer should have a method to test whether or not the timer had expired (i.e., bool expired() ).
I didn't add an expired() method so as to not make it easy write code with a race condition ;) (Although strictly speaking you could check the duration returned by expires_from_now() for the same effect.) The problem with a hypothetical expired() method is that if it returns true it doesn't actually tell you whether the async_wait's handler has been delivered yet, i.e. the timer expired but the handler could be sitting in the demuxer's post queue. Another thing is that changing the timer's expiry time while there are unexpired async_waits has no effect on those waits. In fact I should change the documentation to make it clear that changing the expiry time while there are unexpired waits is "undefined". This design decision was taken for efficiency reasons, i.e. to avoid having getting or setting the expiry time need to access a synchronised resource (e.g. the select_reactor). There are two features you can use to accomplish what you need: - The cancel() function returns the number of async_waits that were cancelled. If it returns 0 then you were too late and you wait handler has been or will soon be executed. If it returns 1 then your handler was successfully cancelled. - If your handler was cancelled, then the asio::error passed to it contains the value operation_aborted. You might use them something like this: void on_keystroke() { if (timer.cancel() > 0) { // We managed to cancel the timer ok. Reset for new timeout. timer.expires_from_now(seconds(5)); timer.async_wait(on_timeout); } else { // Too late, timer has already expired! } } void on_timeout(const asio::error& e) { if (e != asio::error::operation_aborted) { // We were not cancelled, take necessary action. } }
BTW: This library is a joy. When does the review period start? ;)
Thanks! I'm in the process of incorporating a few last changes before 0.3.4 so that after that (I believe, or at least I hope) the interface should be stable. I will then be turning it into boost library format and asking for a review then. As for the actual review date... :) Cheers, Chris