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
source to share
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.
source to share