`boost::asio::thread_pool` `attach()`/`join()` race condition
Opened this issue · 0 comments
This is somewhat related to an issue I reported a while ago: #1230
The following code has a potential deadlock:
asio::thread_pool pool(0);
std::thread thread([&pool]() { pool.attach(); });
pool.join();
thread.join();
The reason is the implementation of thread_pool::join():
void thread_pool::join()
{
if (num_threads_)
scheduler_.work_finished();
if (!threads_.empty())
threads_.join();
}
The problem is the first conditional -- as attach()
happens in a separate thread, it can happen after the first if
check. In that case num_threads_
was 0
& scheduler_.work_finished()
never got called. Both threads get stuck because attach()
never returns.
Now, calling pool.wait()
instead of pool.join()
fixes the problem as it calls scheduler_.work_finished()
unconditionally.
Documentation for both join()
& wait()
is the same, but from the implementation it looks like
join()
will only stop threads if there are any attached & doesn't bother with threads about to attachwait()
will stop currently attached threads & any that might attach in the future
I'm having trouble understanding this if
condition. Would it be wrong to call scheduler_.work_finished()
even if number of threads seems to be 0
?
Ideally for me the implementation for join would be:
void thread_pool::join() { wait(); }