Boost.Asioのdeadline_timerには、Boost 1.47.0からcancel_one()というメンバ関数が追加されます。
元からcancel()というのはあるので、その違いをここで紹介します。
cancel()は、async_waitしてる全てのハンドラをキャンセルします。
戻り値として、キャンセルした個数が返されます。ここでは2。
#include <iostream> #include <string> #include <ctime> #include <boost/asio.hpp> #include <boost/format.hpp> #include <boost/current_function.hpp> namespace asio = boost::asio; std::string now() { std::time_t t; std::time(&t); std::tm* st = std::localtime(&t); return (boost::format(" %1%/%2%/%3% %4%:%5%:%6% : ") % (1900 + st->tm_year) % (1 + st->tm_mon) % st->tm_mday % st->tm_hour % st->tm_min % st->tm_sec ).str(); } void on_timer1(const boost::system::error_code& error) { if (error == asio::error::operation_aborted) std::cout << BOOST_CURRENT_FUNCTION << now() << "cancelled" << std::endl; else if (error) std::cout << BOOST_CURRENT_FUNCTION << now() << "other error" << std::endl; else std::cout << BOOST_CURRENT_FUNCTION << now() << "correct" << std::endl; } void on_timer2(const boost::system::error_code& error) { if (error == asio::error::operation_aborted) std::cout << BOOST_CURRENT_FUNCTION << now() << "cancelled" << std::endl; else if (error) std::cout << BOOST_CURRENT_FUNCTION << now() << "other error" << std::endl; else std::cout << BOOST_CURRENT_FUNCTION << now() << "correct" << std::endl; } int main() { asio::io_service io_service; asio::deadline_timer timer(io_service); std::cout << now() << "start" << std::endl; timer.expires_from_now(boost::posix_time::seconds(2)); timer.async_wait(on_timer1); timer.async_wait(on_timer2); const int count = timer.cancel(); std::cout << "cancel count : " << count << std::endl; io_service.run(); }
2011/6/29 10:27:3 : start cancel count : 2 void __cdecl on_timer1(const class boost::system::error_code &) 2011/6/29 10:27:3 : cancelled void __cdecl on_timer2(const class boost::system::error_code &) 2011/6/29 10:27:3 : cancelled
キャンセルされたハンドラは呼ばれなくなるのではなく、即ハンドラが呼ばれ、error_codeとしてasio::error::operation_abortedが渡されます。
cancel_one()は、タイマーのハンドラキューから先頭ひとつをキャンセルします。
#include <iostream> #include <string> #include <ctime> #include <boost/asio.hpp> #include <boost/format.hpp> #include <boost/current_function.hpp> namespace asio = boost::asio; std::string now() { std::time_t t; std::time(&t); std::tm* st = std::localtime(&t); return (boost::format(" %1%/%2%/%3% %4%:%5%:%6% : ") % (1900 + st->tm_year) % (1 + st->tm_mon) % st->tm_mday % st->tm_hour % st->tm_min % st->tm_sec ).str(); } void on_timer1(const boost::system::error_code& error) { if (error == asio::error::operation_aborted) std::cout << BOOST_CURRENT_FUNCTION << now() << "cancelled" << std::endl; else if (error) std::cout << BOOST_CURRENT_FUNCTION << now() << "other error" << std::endl; else std::cout << BOOST_CURRENT_FUNCTION << now() << "correct" << std::endl; } void on_timer2(const boost::system::error_code& error) { if (error == asio::error::operation_aborted) std::cout << BOOST_CURRENT_FUNCTION << now() << "cancelled" << std::endl; else if (error) std::cout << BOOST_CURRENT_FUNCTION << now() << "other error" << std::endl; else std::cout << BOOST_CURRENT_FUNCTION << now() << "correct" << std::endl; } int main() { asio::io_service io_service; asio::deadline_timer timer(io_service); std::cout << now() << "start" << std::endl; timer.expires_from_now(boost::posix_time::seconds(2)); timer.async_wait(on_timer1); timer.async_wait(on_timer2); timer.cancel_one(); io_service.run(); }
2011/6/29 10:32:0 : start void __cdecl on_timer1(const class boost::system::error_code &) 2011/6/29 10:32:0 : cancelled void __cdecl on_timer2(const class boost::system::error_code &) 2011/6/29 10:32:2 : correct