title: C++11 condition_variable synchronisation issue
body: <p>I have a simple thread pool that needs to be able to wait for its workers to consume all the tasks in the queue without using standard <code>thread::join()</code>, as I don't want to kill the threads themselves but just wait for them to complete all the tasks while staying in their execution loops. I thought of accomplishing this using <code>condition_variable</code>s, like so:</p>
  
  <p><strong>ThreadPool.cpp</strong></p>
  
  <pre><code>void ThreadPool::addTask(ThreadTaskFunction task, void *arg) {
      std::lock_guard&lt;std::mutex&gt; t_lock(task_lock);
      tasks.push_back(ThreadTask(task, arg));
  
      // For every tasks that is added, I increment a counter
      assignedTasks++;
  }
  
  void ThreadPool::join() {
      std::unique_lock&lt;std::mutex&gt; lock(join_lock);
      joinCondition.wait(lock, [this](){
          return assignedTasks == 0;
      });
  }
  </code></pre>
  
  <p><strong>Thread.cpp</strong>
  Note that this is a friend class to ThreadPool</p>
  
  <pre><code>void Thread::threadLoop() {
      while (!shouldDie) {
          ThreadTask task;
  
          if (pool.hasTasks()) {
              {
                  std::lock_guard&lt;std::mutex&gt; lock(pool.task_lock);
  
                  if (!pool.hasTasks()) continue;
  
                  task = pool.getTask();
              }
  
              task.function(task.argument);
              this-&gt;completeTask();
          }
      }
  
      this-&gt;isThreadFinished = true;
  }
  
  void Thread::completeTask() {
      std::lock_guard&lt;std::mutex&gt; guard(pool.task_lock);
  
      // When a task is completed, I decrement the counter and notify the main thread that a task has completed.
      pool.assignedTasks--;    
      pool.joinCondition.notify_one();
  }
  </code></pre>
  
  <p>I'm using this thing for a physics simulation, and this stuff happens on every step of said simulation (around once every 16ms). What happens is that after a few hundred steps, everything stops because somehow a notify signal is sent <strong>before</strong> the main thread enters the wait status, probably because it's checking the condition. If I debug, I can see that I have one task left on the counter, no tasks running on the threads, no tasks in the queue and nothing really happening anymore. Sometimes, even weirder, everything unlocks as soon as I pause execution with a breakpoint and restart it. I've tried putting more locks in place to no avail.
  Is there something obvious that I'm missing?</p>
  
  <p><strong>UPDATE</strong> It appears that the problem is solved by setting the <code>assignedTasks</code> variable as <code>volatile</code>. It's getting modified so often that sometimes the value in the registers is not updated and everything stops. Never had to do this before. Huh. :)</p>