Post by Yuval RonenPost by Christopher KohlhoffPost by Yuval Ronen[this a copy of a post sent to the Boost.Users list]
The Asio docs for deadline_timer::cancel say that "This function forces
the completion of any pending asynchronous wait operations against the
timer". Let's say I have a thread executing io_service::run, and is now
invoking a completion handler of a deadline_timer. While this completion
handler is underway, a second thread is calling cancel() on that
deadline_timer. Is the cancel() call supposed to block until the
completion handler is finished? To my best understanding, both according
to the docs, and according to what seems to be logical to me, the answer
is "yes, it should block".
I'm curious: why do you think that would be the logical approach?
Let's say I have a class (MyClass) which contains an instance of
deadline_timer, in order to perform a specific task every 10 seconds, as
long the MyClass instance is alive. I use the technique demonstrated by
Timer.4 tutorial example, of calling timer.expires_at() and
timer.async_wait() from the timer completion handler.
The d'tor of MyClass needs to stop execution of that specific task. How
to do it? AFAIU, I need to do it using timer.cancel(). The d'tor is
called in a different thread than the thread that execute the completion
handler (which is the thread calling io_service::run). So let's assume
the completion handler has just begun executing at some point, and then
there is a context switch. The other thread is calling
MyClass::~MyClass, and then there is another context switch. The first
thread continues the completion handler, and in the end it tries to
activate the timer (expires_at & async_wait). However, at that point the
deadline_timer is already destroyed! The timer d'tor was already called
(from MyClass d'tor)...
I can supply some code if necessary.
Post by Christopher KohlhoffPost by Yuval RonenHowever, it doesn't. Is it a bug, or by design?
That's the way it is designed to work. The cancel() function is
essentially a non-blocking request for the timer to cancel any
outstanding operations.
- You set the timer's expiry using expires_at() or expires_from now().
- You call async_wait() to initiate the operation.
- The timer expires "in the background" and the completion handler is
posted (as-if by calling io_service::post()) for execution. At this
point the handler is decoupled from the timer. The timer's work is done
and the asynchronous wait operation is no longer pending.
- The completion handler is executed from inside io_service::run(). The
timer is not involved in any way.
- You call cancel() from another thread. The timer has nothing to cancel.
If you actually want your code to block until a specific completion
handler has executed then you will want to look at using something like
a future.
OK, I now understand better how the deadline_timer interacts with the
io_service. The problem is, as I described above, that I can't implement
a recurring asynchronous timer. Or is there a way I didn't think of?
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
canceled/completed.