Asio timer - how to restart it?
Hello,
I'm writing an Asio based serial port communication application.
I've tried to use Asio timer as receive time out timer.
The implementation consist of restarting the timer each time the receive
event is called,
, so it'll trigger only after time out duration with no receive event.
The problem is that when I try to restart the timer, using
expires_from_now(), the timer immediately
triggers.
I've written a simplified code that demonstrate this problem:
#include <iostream>
#include
Hi,
As you can see to on_time_out() is called immediately after expires_from_now() call, with no actual time out.
How do I restart to timer in the right way?
You could check error code in handler, in case of cancellation (including settings new expiration time) it contains the value boost::asio::error::operation_aborted. Best Regards, Sergei
Peleg wrote:
Hello, I'm writing an Asio based serial port communication application. I've tried to use Asio timer as receive time out timer. The implementation consist of restarting the timer each time the receive event is called, , so it'll trigger only after time out duration with no receive event. The problem is that when I try to restart the timer, using expires_from_now(), the timer immediately triggers.
You are not getting asynchronous timeouts, all you are seeing is the first timer being cancelled when you queue the second. All asio async actions happen in the context of the io_service, you need to call io_service.run() somewhere. You have either oversimplified your example or you need to re-read the asio examples. HTH Bill Somerville ...
How do I restart to timer in the right way?
Thanks, Peleg
Bill Somerville wrote:
Peleg wrote:
Hello, I'm writing an Asio based serial port communication application. I've tried to use Asio timer as receive time out timer. The implementation consist of restarting the timer each time the receive event is called, , so it'll trigger only after time out duration with no receive event. The problem is that when I try to restart the timer, using expires_from_now(), the timer immediately triggers.
You are not getting asynchronous timeouts, all you are seeing is the first timer being cancelled when you queue the second.
All asio async actions happen in the context of the io_service, you need to call io_service.run() somewhere.
You have either oversimplified your example or you need to re-read the asio examples. Sorry, ignore my response - I didn't look at your code closely enough!
Igor R is correct, you have prematurely cancelled your first timer.
HTH Bill Somerville
...
How do I restart to timer in the right way? Thanks, Peleg
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Bill Somerville
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5)); boost::thread thread(boost::bind(&boost::asio::io_service::run, &io)); timer.async_wait(on_time_out); delay(3);
Note that you set the timer timeout to be 5 second, but wait 3 second only.
cout << second_clock::local_time() << " Restarting timer" << endl; timer.expires_from_now(boost::posix_time::seconds(5));
You just change the timeout here. To restart the timer you have to call timer.async_wait(). By the way, note that the timer is not threadsafe so I'm not sure it's legal to restart it here or to change its timeout this way.
Igor R wrote:
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5)); boost::thread thread(boost::bind(&boost::asio::io_service::run, &io)); timer.async_wait(on_time_out); delay(3);
Note that you set the timer timeout to be 5 second, but wait 3 second only.
cout << second_clock::local_time() << " Restarting timer" << endl; timer.expires_from_now(boost::posix_time::seconds(5));
You just change the timeout here. To restart the timer you have to call timer.async_wait(). By the way, note that the timer is not threadsafe so I'm not sure it's legal to restart it here or to change its timeout this way. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks, that's it, now how do I filter only successful timer triggers? I added the following line to on_time_out(): cout << "Error #" << error << ": " << error.message() << endl; And successful call resulted the following output: Error #system:0: The operation completed successfully but I failed to find the correct error_code value I've tried: if(error == boost::asio::error::success) and if(error == boost::system::error::success) but non of them is valid, what is the valid success condition? thanks again, Peleg -- View this message in context: http://www.nabble.com/Asio-timer---how-to-restart-it--tp20128401p20134911.ht... Sent from the Boost - Users mailing list archive at Nabble.com.
Thanks, that's it, now how do I filter only successful timer triggers? I added the following line to on_time_out():
http://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/reference/basic_dea... "For each call to async_wait(), the supplied handler will be called exactly once. The handler will be called when: * The timer has expired. * The timer was cancelled, in which case the handler is passed the error code boost::asio::error::operation_aborted." So usually you test it like this: void handler(const boost::system::error_code &err) { if (err != boost::asio::error::operation_aborted) { // do what you want } //or: if (err && err != boost::asio::error::operation_aborted) { //... } }
participants (4)
-
Bill Somerville
-
Igor R
-
Peleg
-
Sergei Politov