title: Possible race condition in std::condition_variable?
body: <p>I've looked into the VC++ implementation of <code>std::condition_variable(lock,pred)</code>, basically, it looks like this:</p>
  
  <pre><code>template&lt;class _Predicate&gt;
          void wait(unique_lock&lt;mutex&gt;&amp; _Lck, _Predicate _Pred)
          {   // wait for signal and test predicate
          while (!_Pred())
              wait(_Lck);
          }
  </code></pre>
  
  <p>Basically , the naked <code>wait</code> calls <code>_Cnd_waitX</code> which calls <code>_Cnd_wait</code>which calls <code>do_wait</code> which calls <code>cond-&gt;_get_cv()-&gt;wait(cs);</code> (all of these are in the file cond.c). <br/></p>
  
  <p><code>cond-&gt;_get_cv()</code> returns <code>Concurrency::details::stl_condition_variable_interface</code> .</p>
  
  <p>If we go to the file <code>primitives.h</code>, we see that under windows 7 and above, we have the class <code>stl_condition_variable_win7</code> which contains the old good win32 <code>CONDITION_VARIABLE</code>, and <code>wait</code> calls <code>__crtSleepConditionVariableSRW</code>.</p>
  
  <p>Doing a bit of assembly debug, <code>__crtSleepConditionVariableSRW</code> just extract the the <code>SleepConditionVariableSRW</code> function pointer, and calls it.</p>
  
  <p>Here's the thing: as far as I know, the win32 <code>CONDITION_VARIABLE</code> is not a kernel object, but a user mode one. Therefore, if some thread notifies this variable and no thread actually sleep on it, you lost the notification, and the thread will remain sleeping until timeout has reached or some other thread notifies it. A small program can actually prove it - if you miss the point of notification - your thread will remain sleeping although some other thread notified it.</p>
  
  <p>My question goes like this: <br/>
  one thread waits on a condition variable and the predicate returns false. Then, the whole chain of calls explained above takes place. In that time, another thread changed the environment so the predicate will return true <em>and</em> notifies the condition variable. We passed the predicate in the original thread, but we still didn't get into <code>SleepConditionVariableSRW</code> - the call chain is very long.</p>
  
  <p>So, although we notified the condition variable <strong>and</strong> the predicate put on the condition variable will definitely return true (because the notifier made so), we are still blocking on the condition variable, possibly forever.</p>
  
  <p>Is this how should it behave? It seems like a big ugly race condition waiting to happen. If you notify a condition variable and it's predicate returns true - the thread should unblock. But if we're in the limbo between checking the predicate and going to sleep - we are blocked forever. <code>std::condition_variable::wait</code> is not an atomic function.</p>
  
  <p>What does the standard says about it and is it a really race condition? </p>