title: Thread pool stuck on wait condition
body: <p>I'm encountering a stuck in my c++ program using this thread pool class:</p>
  
  <pre><code>class ThreadPool {
  
      unsigned threadCount;
      std::vector&lt;std::thread&gt; threads;
      std::list&lt;std::function&lt;void(void)&gt; &gt; queue;
  
      std::atomic_int jobs_left;
      std::atomic_bool bailout;
      std::atomic_bool finished;
      std::condition_variable job_available_var;
      std::condition_variable wait_var;
      std::mutex wait_mutex;
      std::mutex queue_mutex;
      std::mutex mtx;
  
      void Task() {
          while (!bailout) {
              next_job()();
              --jobs_left;
              wait_var.notify_one();
         }
      }
  
      std::function&lt;void(void)&gt; next_job() {
          std::function&lt;void(void)&gt; res;
          std::unique_lock&lt;std::mutex&gt; job_lock(queue_mutex);
  
          // Wait for a job if we don't have any.
          job_available_var.wait(job_lock, [this]()-&gt;bool { return queue.size() || bailout; });
  
          // Get job from the queue
          mtx.lock();
          if (!bailout) {
              res = queue.front();
              queue.pop_front();
          }else {
              // If we're bailing out, 'inject' a job into the queue to keep jobs_left accurate.
              res = [] {};
              ++jobs_left;
          }
          mtx.unlock();
          return res;
      }
  
  public:
      ThreadPool(int c)
          : threadCount(c)
          , threads(threadCount)
          , jobs_left(0)
          , bailout(false)
          , finished(false)
      {
          for (unsigned i = 0; i &lt; threadCount; ++i)
              threads[i] = std::move(std::thread([this, i] { this-&gt;Task(); }));
      }
  
      ~ThreadPool() {
          JoinAll();
      } 
  
      void AddJob(std::function&lt;void(void)&gt; job) {
          std::lock_guard&lt;std::mutex&gt; lock(queue_mutex);
          queue.emplace_back(job);
          ++jobs_left;
          job_available_var.notify_one();
      }
  
      void JoinAll(bool WaitForAll = true) {
          if (!finished) {
              if (WaitForAll) {
                  WaitAll();
              }
  
              // note that we're done, and wake up any thread that's
              // waiting for a new job
              bailout = true;
              job_available_var.notify_all();
  
              for (auto&amp; x : threads)
                  if (x.joinable())
                      x.join();
              finished = true;
          }
      }
  
      void WaitAll() {
          std::unique_lock&lt;std::mutex&gt; lk(wait_mutex);
          if (jobs_left &gt; 0) {
              wait_var.wait(lk, [this] { return this-&gt;jobs_left == 0; });
          }
          lk.unlock();
      }
  };
  </code></pre>
  
  <p>gdb say (when stopping the blocked execution) that the stuck was in (std::unique_lock&amp;, ThreadPool::WaitAll()::{lambda()#1})+58></p>
  
  <p>I'm using g++ v5.3.0 with support for c++14 (-std=c++1y)</p>
  
  <p>How can I avoid this problem?</p>
  
  <h2>Update</h2>
  
  <p>I've edited (rewrote) the class: <a href="https://github.com/edoz90/threadpool/blob/master/ThreadPool.h" rel="nofollow">https://github.com/edoz90/threadpool/blob/master/ThreadPool.h</a></p>