Description
I have noticed that there seems to be a race condition in the shutdown process of ThreadPool. By example let Thread1 be the main thread executing shutdown()
and let Thread2 be a ThreadWorker executing operator(). If we take the following interleaving of calls (assuming that the queue is empty by the start):
Thread2: checks the while condition and returns true.
Thread1: sets m_shutdown to false.
Thread1: calls m_conditional_lock.notify_all().
Thread2: takes ownership of m_pool->m_conditional_mutex.
Thread2: call m_pool->m_conditional_lock.wait( lock ).
In the above scenario it can be seen that the notify_all() is completed before Thread2 calls wait which means that the ThreadWorker remains waiting indefinitely (unless a spurious wake-up occurs) and so the call to join() in shutdown() can't be completed stopping the shutdown of the thread pool. One suggestion to fix this would be to provide a predicate to the wait(lock), such as m_pool->m_conditional_lock.wait( lock , [this]{ return (!this->m_pool->m_queue.empty()) || this->m_pool->m_shutdown;});