title: Destruction of condition variable randomly loses notification
body: <p>Given a condition_variable as a member of a class, my understanding is that:</p>
  
  <ol>
  <li><a href="https://stackoverflow.com/questions/28356069/what-order-are-destructors-called-and-member-variables-destroyed-in-c-using-in">The condition variable is destroyed after the class destructor completes.</a></li>
  <li><a href="http://en.cppreference.com/w/cpp/thread/condition_variable/%7Econdition_variable" rel="noreferrer">Destruction of a condition variable does not need to wait for notifications to have been received.</a></li>
  </ol>
  
  <p>In light of these expectations, my question is: why does the example code below <em>randomly</em> fail to notify a waiting thread?</p>
  
  <pre><code>#include &lt;mutex&gt;
  #include &lt;condition_variable&gt;
  #define NOTIFY_IN_DESTRUCTOR 
  
  struct notify_on_delete {
      std::condition_variable cv;
  
      ~notify_on_delete() {
  #ifdef NOTIFY_IN_DESTRUCTOR
          cv.notify_all();
  #endif
      }
  };
  
  int main () {
      for (int trial = 0; trial &lt; 10000; ++trial) {
          notify_on_delete* nod = new notify_on_delete();
          std::mutex flag;
          bool kill = false;
  
          std::thread run([nod, &amp;flag, &amp;kill] () {
              std::unique_lock&lt;std::mutex&gt; lock(flag);
              kill = true;
              nod-&gt;cv.wait(lock);
          });
  
          while(true) {
              std::unique_lock&lt;std::mutex&gt; lock(flag);
              if (!kill) continue;
  #ifdef NOTIFY_IN_DESTRUCTOR
              delete nod;
  #else
              nod-&gt;cv.notify_all();
  #endif
              break;
          }
          run.join();
  #ifndef NOTIFY_IN_DESTRUCTOR
          delete nod;
  #endif
      }
      return 0;
  }
  </code></pre>
  
  <p>In the code above, if NOTIFY_IN_DESTRUCTOR is not defined then the test will run to completion reliably. However, when NOTIFY_IN_DESTRUCTOR is defined the test will <em>randomly</em> hang (usually after a few thousand trials).</p>
  
  <p>I am compiling using Apple Clang:
  Apple LLVM version 9.0.0 (clang-900.0.39.2)
  Target: x86_64-apple-darwin17.3.0
  Thread model: posix
  C++14 specified, compiled with DEBUG flags set.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>To clarify: this question is about the semantics of the specified behavior of instances of condition_variable. The second point above appears to be reenforced in the following <a href="https://timsong-cpp.github.io/cppwp/thread.condition.condvar#5" rel="noreferrer">quote</a>:</p>
  
  <blockquote>
    <p>Blockquote
    Requires: There shall be no thread blocked on *this. [ Note: That is, all threads shall have been notified; they may subsequently block on the lock specified in the wait. This relaxes the usual rules, which would have required all wait calls to happen before destruction. Only the notification to unblock the wait needs to happen before destruction. The user should take care to ensure that no threads wait on *this once the destructor has been started, especially when the waiting threads are calling the wait functions in a loop or using the overloads of wait, wait_­for, or wait_­until that take a predicate. — end note ]</p>
  </blockquote>
  
  <p>The core semantic question seems to be what "blocked on" means. My present interpretation of the quote above would be that after the line</p>
  
  <pre><code>cv.notify_all(); // defined NOTIFY_IN_DESTRUCTOR
  </code></pre>
  
  <p>in ~notify_on_delete() the thread test is <em>not</em> "blocked on" nod - which is to say that I presently understand that after this call "the notification to unblock the wait" <em>has</em> occurred, so according to the quote the requirement has been met to proceed with the destruction of the condition_variable instance.</p>
  
  <p>Can someone provide a clarification of "blocked on" or "notification to unblock" to the effect that in the code above, the call to notify_all() does not satisfy the requirements of ~condition_variable()?</p>