[asio-users] Race condition between io_service::run() and io_service::post()
Brought to you by:
chris_kohlhoff
From: ivan k. <ik...@gm...> - 2016-12-09 12:26:49
|
Dear ASIO users, I want to use io_service as a thread pool for CPU intensive operations. It is important for me to not loose any jobs pending in the queue when stopping it. So according to the boost documentation I'm using io_service::work for this purpose. When I need to stop the pool from running I just destruct the work. However the unittest which you can find at the end of the e-mail issues a race condition warning from the clang's thread sanitizer ( clang 3.8, ubuntu 14.04 ). After modifying the singal_and_unlock function in the posix_event.hpp the warning is gone and the unittest runs without issues. // Signal the event and unlock the mutex. template <typename Lock> void signal_and_unlock(Lock& lock) { BOOST_ASIO_ASSERT(lock.locked()); signalled_ = true; // lock.unlock(); ::pthread_cond_signal(&cond_); // Ignore EINVAL. lock.unlock(); } Is this a real bug, or am I doing something wrong ? If it is a bug, where should I post it ? Thank you in advance, Ivan Unittest BOOST_AUTO_TEST_CASE(ioServiceShallWaitForPendingJobs) { auto test = []() { boost::asio::io_service service; std::unique_ptr<boost::asio::io_service::work> work (new boost::asio::io_service::work(service)); std::thread t( [&service]() { service.run(); } ); std::atomic_bool called{false}; service.post( [&called]() { std::this_thread::sleep_for (std::chrono::milliseconds(50)); called = true; } ); std::this_thread::sleep_for (std::chrono::milliseconds(1)); work.reset(); // -> leak t.join(); BOOST_REQUIRE(called); }; for( size_t i = 0 ; i < 100000; ++i) { BOOST_TEST_MESSAGE(i); test(); } } |