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 attach
wait() 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:
This is somewhat related to an issue I reported a while ago: https://github.com/chriskohlhoff/asio/pull/1230
The following code has a potential deadlock:
The reason is the implementation of thread_pool::join():
The problem is the first conditional -- as
attach()
happens in a separate thread, it can happen after the firstif
check. In that casenum_threads_
was0
&scheduler_.work_finished()
never got called. Both threads get stuck becauseattach()
never returns.Now, calling
pool.wait()
instead ofpool.join()
fixes the problem as it callsscheduler_.work_finished()
unconditionally.Documentation for both
join()
&wait()
is the same, but from the implementation it looks likejoin()
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 futureI'm having trouble understanding this
if
condition. Would it be wrong to callscheduler_.work_finished()
even if number of threads seems to be0
?Ideally for me the implementation for join would be: