Boost logo

Boost Users :

Subject: Re: [Boost-users] [Asio] Does stop() cancel handlers post()ed to io_service?
From: Marat Abrarov (abrarov_at_[hidden])
Date: 2013-06-25 16:05:36


> 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.

It would be more accurate to say "on Windows asio::io_service::stop()
does not cancel already queued (!) handlers". See example below.

~~~~~~~~~~~~~~~~~~~~~~~

#if defined(WIN32)
#include <tchar.h>
#endif

#include <cstdlib>
#include <cstddef>
#include <iostream>
#include <boost/ref.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>

namespace {

typedef boost::function<void (boost::asio::io_service&)> work_factory;

void run_test(work_factory wf)
{
  {
    boost::asio::io_service io_service;
    {
      wf(io_service);
      std::cout << "io_service work created" << std::endl;
      {
        std::cout << "work thread starting..." << std::endl;
        boost::thread work_thread(boost::bind(
            &boost::asio::io_service::run, boost::ref(io_service)));
        boost::this_thread::sleep(boost::posix_time::millisec(300));
        io_service.stop();
        std::cout << "io_service signalled to stop" << std::endl;
        work_thread.join();
        std::cout << "work thread stopped" << std::endl;
      }
    }
    std::cout << "destroying io_service..." << std::endl;
  }
  std::cout << "io_service destroyed" << std::endl;
}

void test_function1()
{
  static int counter = 0;
  std::cout << "handler #" << counter++ << std::endl;
  boost::this_thread::sleep(boost::posix_time::millisec(100));
}

void post_test_function1(boost::asio::io_service& io_service)
{
  for (std::size_t i = 0; i != 10; ++i)
  {
    io_service.post(&test_function1);
  }
}

void post_test_function2(boost::asio::io_service&);

void test_function2(boost::asio::io_service& io_service)
{
  static int counter = 0;
  std::cout << "handler #" << counter++ << std::endl;
  boost::this_thread::sleep(boost::posix_time::millisec(100));
  post_test_function2(io_service);
}

void post_test_function2(boost::asio::io_service& io_service)
{
  io_service.post(boost::bind(test_function2, boost::ref(io_service)));
}

} // anonymous namespace

#if defined(WIN32)
int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
#else
int main(int /*argc*/, char* /*argv*/[])
#endif
{
  std::cout << "Test 1" << std::endl;
  run_test(post_test_function1);

  std::cout << std::endl << "Test 2" << std::endl;
  run_test(post_test_function2);

  return EXIT_SUCCESS;
}

~~~~~~~~~~~~~~~~~~~~~~~

Regards,
Marat Abrarov.


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