Boost logo

Boost :

From: Christopher Kohlhoff (chris_at_[hidden])
Date: 2005-09-28 20:36:09


Hi Dick,

--- BRIDGES Dick <Dick.Bridges_at_[hidden]> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk