Reputation: 53
From Asio documentation
The run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped.
In the following snippet Asio has no work apart from debug output (which is instantly computed), 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;
}
The output before hang is
@asio|1433598048.101578|0*1|[email protected]
@asio|1433598048.101785|>0|
before run()
socket is closed
Without socket this snippet works just fine.
I'm using Ubuntu 15.04 and I 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 I just misunderstand something?
UPDATE
This bug is reproducing only with following file, that must be compiled together with above snippet in other 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 minimal project at https://github.com/shadeware/asio-problem
Upvotes: 4
Views: 1654
Reputation: 15841
Apparently if you choose to define BOOST_ASIO_ENABLE_HANDLER_TRACKING
then you must do so in all boost::asio
translation units. I don't see this mentioned in the documentation, but I did find it on the Boost mailing list.
When I add
add_definitions(-DBOOST_ASIO_ENABLE_HANDLER_TRACKING)
to your CMakeLists.txt
so it is applied globally then I don't see the hang.
Upvotes: 3