Boost logo

Boost Users :

Subject: [Boost-users] [Asio] Does stop() cancel handlers post()ed to io_service?
From: Martin Gernhard (gernhard.martin_at_[hidden])
Date: 2013-06-25 08:58:40


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;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net