Boost :: asio :: io_service :: run does not return when not running

From Asio documentation

The run () function will block until all work has finished and no more handlers have been dispatched or until io_service is stopped.

In the following snippet, Asio does not work except for debug output (which is computed instantly), but run () does not return.

#define BOOST_ASIO_ENABLE_HANDLER_TRACKING

#include <iostream>
#include <thread>

#include <boost/asio.hpp>

int main()
{
  namespace asio = boost::asio;

  asio::io_service ios;

  asio::ip::udp::endpoint ep(boost::asio::ip::udp::v4(), 9876);
  auto socket = new asio::ip::udp::socket(ios, ep);
  std::thread th([&]
  {
      ios.dispatch([]{ std::cout << "before run()" << std::endl;});
      ios.run();
      std::cout << "after run()" << std::endl;
  });

  std::this_thread::sleep_for(std::chrono::seconds(5)); // wait for io_service to launch

  socket->cancel();
  socket->close();
  delete socket; // just in case

  std::cout << "socket is closed" << std::endl;

  th.join(); // hangs here

  std::cout << "exiting..." << std::endl;
}

      

Exit before hanging

@asio|1433598048.101578|0*1|io_service@0x611000009f00.dispatch
@asio|1433598048.101785|>0|
before run()
socket is closed

      

Without a socket, this snippet works fine.

I am using Ubuntu 15.04 and I have tried gcc-4.9.2, gcc-5.1, clang-3.6, boost-1.56 and boost-1.58.

Is this a bug, and if so, is there any workaround, or am I just misunderstanding something?

UPDATE
This error is reproducible only with the following file, which must be compiled along with the above snippet into a different translation unit:

#include <boost/asio.hpp>

namespace asio = boost::asio;

class my_server
{
public:
  my_server(asio::io_service& ios);

private:

  asio::io_service& _ios;
  asio::ip::udp::socket _socket;
};

my_server::my_server(boost::asio::io_service &ios)
  : _ios(ios), _socket(ios, asio::ip::udp::endpoint())
{
}

      

I created a minimal project https://github.com/shadeware/asio-problem

+3


source to share


1 answer


Apparently, if you choose to define BOOST_ASIO_ENABLE_HANDLER_TRACKING

, you must do so in all translation units boost::asio

. I don't see this in the documentation, but I found it on the Boost listing list .

When I add



add_definitions(-DBOOST_ASIO_ENABLE_HANDLER_TRACKING)

      

to yours CMakeLists.txt

, so it is applied globally, then I don't see the hang.

+1


source







All Articles