ahojnnes · GitHub

Fix a bug where the Stop function's state issue may cause the Pop()
function to enter an infinite loop.
template <typename T>
void JobQueue<T>::Stop() {
    stop_ = true; // problem code
  push_condition_.notify_all();
  pop_condition_.notify_all();
}
typename JobQueue<T>::Job JobQueue<T>::Pop() {
  std::unique_lock<std::mutex> lock(mutex_);
  while (jobs_.empty() && !stop_) {
    push_condition_.wait(lock);
  ....
​​Bug Description:​​
There is a race condition between Stop() and Pop() that can lead to
deadlock. The sequence is:
In Pop(), the thread evaluates while (jobs_.empty() && !stop_) and sees
stop_ = false
Before entering push_condition_.wait(lock), the Stop() function gets
executed:
Sets stop_ = true
Calls push_condition_.notify_all()
The Pop() thread then proceeds to push_condition_.wait(lock)
Because the notification was sent before the wait began, it's missed
Now the thread is stuck waiting indefinitely with stop_ = true, causing
a deadlock
---------
Co-authored-by: 3000huyang <3000huyang@163.com>
Co-authored-by: Johannes Schönberger <jsch@meta.com>
Co-authored-by: Johannes Schönberger <jsch@demuc.de>

Read the original on github.com ↗