[Asio] Does stop() cancel handlers post()ed to io_service?

Hello, I want to cancel all pending handlers of an io_service. Is io_service::stop() supposed to cancel handlers that have been added using post()? The documentation for stop() is somewhat ambiguous on this matter, only stating that run() "should return as soon as possible". Alternatively, should the destructor of io_service cancel the handlers? I am trying to build a "worker thread" using Boost.Asio (1.53) and Boost.Thread as outlined at http://think-async.com/Asio/Recipes. I have already looked at the documentation and searched the bug tracker, the mailing list archives, Google and Stack Overflow but only found an unanswered message from almost two years ago (http://lists.boost.org/boost-users/2011/09/70596.php) as well as another message that describes different behavior of stop() than what I am experiencing (http://thread.gmane.org/gmane.comp.lib.boost.user/73762). The program below gives different results on Windows (Visual Studio 2008) and Linux. While stop() does cancel the handlers on Linux, the same is not true for Windows. I also tried to destroy the io_service object instead of calling stop, but this does not cancel the handlers on either system, even though the documentation seems to state it should. Result on Windows for stop() and ~io_service and on Linux for ~io_service: Start 0 1 2 Stop 3 4 5 6 7 8 9 Result on Linux for stop(): Start 0 1 2 Stop For now I am using the workaround of querying a boost::atomic<bool> flag from every handler and setting it to false after calling stop(). Is there a better way to achieve this, maybe by implementing a custom IO object / service? It feels like overkill for something seemingly simple. Regards, Martin #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/scoped_ptr.hpp> #include <boost/thread.hpp> #include <iostream> using namespace boost; using namespace boost::asio; void testFunction() { static int counter = 0; std::cout << counter++ << std::endl; this_thread::sleep( posix_time::millisec( 100 ) ); } int main() { shared_ptr<io_service> m_ioService(new io_service()); scoped_ptr<io_service::work> m_work(new io_service::work(*m_ioService)); scoped_ptr<thread> m_thread; for ( unsigned int i = 0; i != 10; ++i ) { m_ioService->post( &testFunction ); } std::cout << "Start" << std::endl; m_thread.reset( new thread( bind( &io_service::run, m_ioService ) ) ); this_thread::sleep( posix_time::millisec( 300 ) ); std::cout << "Stop" << std::endl; m_work.reset(); m_ioService->stop(); m_thread->join(); m_thread.reset(); m_ioService->reset(); return 0; }
participants (1)
-
Martin Gernhard