
Christopher Kohlhoff wrote:
Hi Andrew,
--- Andrew Schweitzer <a.schweitzer.grps@gmail.com> 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