I suggest creating a class for the deadline_timer
shell using composition. To cancel it, set the flag to remember that it was canceled. In the handler, reset the flag. When calling expires_from_now()
do not set the flag.
#include <boost/asio.hpp> #include <boost/thread.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time_io.hpp> #include <iostream> class Timer { public: Timer( const std::string& name, boost::asio::io_service& io_service ) : _name( name ), _timer( io_service ), _cancelled( false ) { _timer.expires_from_now( boost::posix_time::seconds(0) ); this->wait(); } void wait() { _timer.async_wait( boost::bind( &Timer::handler, this, boost::asio::placeholders::error ) ); } void cancel() { _cancelled = true; _timer.cancel(); } void restart() { _timer.expires_from_now( boost::posix_time::seconds(5) ); } private: void handler( const boost::system::error_code& error ) { if ( !error ) { std::cout << _name << " " << __FUNCTION__ << std::endl; _timer.expires_from_now( boost::posix_time::seconds(5) ); this->wait(); } else if ( error == boost::asio::error::operation_aborted && _cancelled ) { _cancelled = false; std::cout << _name << " " << __FUNCTION__ << " cancelled" << std::endl; } else if ( error == boost::asio::error::operation_aborted ) { std::cout << _name << " " << __FUNCTION__ << " retriggered" << std::endl; this->wait(); } else { std::cout << "other error: " << boost::system::system_error(error).what() << std::endl; } } private: const std::string _name; boost::asio::deadline_timer _timer; bool _cancelled; }; int main() { boost::asio::io_service ios; Timer timer1( "timer1", ios ); Timer timer2( "timer2", ios ); boost::thread thread( boost::bind( &boost::asio::io_service::run, boost::ref(ios) ) ); sleep( 3 ); std::cout << "cancelling" << std::endl; timer1.cancel(); timer2.restart(); thread.join(); }
trial session
macmini:stackoverflow samm$ ./a.out timer1 handler timer2 handler cancelling timer1 handler cancelled timer2 handler retriggered timer2 handler ^C macmini:stackoverflow samm$
source share