|
Boost : |
From: Andrew Schweitzer (a.schweitzer.grps_at_[hidden])
Date: 2005-12-29 11:20:54
Christopher Kohlhoff wrote:
> Hi Andrew,
>
> --- Andrew Schweitzer <a.schweitzer.grps_at_[hidden]> wrote:
> <snip>
>
>>I suppose what I meant was that in order to prevent the timer
>>from dispatching when the deadline_timer goes out of scope you
>>have to prevent the deadline_timer from destructing, which
>>probably often means dynamically allocating it.
>>
>>Now that I think about it... how are you expecting the
>>deadline_timer object to be used? I assume it shouldn't just
>>go out of scope. Since we might want to keep it around to
>>cancel, presumably we shouldn't pass it to the handler to
>>delete, or we could be canceling a deleted object... although
>>this is what I'm actually doing in my code.... So are you
>>expecting some data structure to keep it around? And then how
>>should it be cleaned up?
>
>
> In my experience a timer is often a data member of a class where
> the objects are relatively long-lived, e.g. a class used to
> manage a connection. The same timer is often reused by adjusting
> the expiry time and reissuing an asynchronous wait. There's no
> need to clean up the timer if there are no asynchronous waits on
> it.
Ah, yes.
>
> You can allocate a timer dynamically for a single asynchronous
> wait if you want, but this is not required.
>
>
>>A related question: how do you ask whether a timer is still
>>running? I think you could call expires_at() and compare to
>>current time. It looks like there might be two issues with
>>this: 1) Will crash if the timer is expired? (haven't tried
>>just took a quick look at code). 2) Oddly enough getting the
>>current time can be quite expensive, for example on Wince (I
>>think because you have to get data from the kernel). It might
>>be a lot faster to just say "I'm expired" if impl_ is null.
>
>
> For applications that need to know whether the timer has fired
> (for use cases other than cancelling the timer) the best thing
> to do is probably just to set some state in the timer's
> associated handler.
Got it.
>
> It might help to keep in mind that a timer is really no more
> than an expiry time. Because of that, explicitly checking
> whether a time object has expired must involve a comparison with
> the system time. An asynchronous wait on the timer is a request
> to be informed when the timer's expiry time has passed, and
> except for cancellation is decoupled from the timer itself.
>
>
>>Good question. At this point I don't see our use case
>>occurring with asio. It's what I'm used to, and it seems like
>>a good idea, possibly just from habit, but maybe there's an
>>underlying reason. I think it comes down to whether the user's
>>context usually naturally provides enough easily bindable data
>>to differentiate between past and multiple current executions
>>of the handler. Also, I think this data might need to be
>>stored by the user outside of the deadline_timer so that the
>>user can decide which timer to cancel, or check which timers
>>are running. My sense is that by invoking the same code over
>>and over again asynchronously we are just asking to be
>>confused about which invocation we are in. It might be nice if
>>the library just generated a unique 32 or 64 bit value for
>>each timer. Or maybe that's more trouble than it's worth.
>
>
> In applications I have seen using asio, the cancellation
> protocol I outlined in my other response has been sufficient.
>
> What I think you're talking about is more accurately described
> as an async_wait id.
That's an interesting distinction.
> For example, you could do something like
> this:
>
> class foobar
> {
> ...
>
> int async_wait_id_;
> deadline_timer timer_;
>
> void start_new_wait()
> {
> timer_.cancel();
> timer_.expires_at(...);
> timer_.async_wait(
> boost::bind(
> &foobar::handle_timeout,
> ++async_wait_id_));
> }
>
> void handle_timeout(int my_wait_id)
> {
> if (my_wait_id == async_wait_id_)
> {
> // This was the active wait ...
> }
> }
> };
>
That is basically what I have been doing. It might be nice if the
library embedded these features (an async wait ID and a flag indicating
completion), rather than the user. But unless other people out there use
these, they are probably not general enough to burden the library with.
> Cheers,
> Chris
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk