<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - condition_variable::wait_for () should always unlock/lock"
   href="https://bugs.llvm.org/show_bug.cgi?id=37818">37818</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>condition_variable::wait_for () should always unlock/lock
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>6.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>lewis@sophists.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Note - similar to 21395, except reasoning is very different.

<a href="http://en.cppreference.com/w/cpp/thread/condition_variable/wait_for">http://en.cppreference.com/w/cpp/thread/condition_variable/wait_for</a> says:

   ... Atomically releases lock, blocks the current executing thread, and adds
it to the list of threads waiting on *this

For the most part this is true with the libc++ implementation, but not when
       if (__d <= __d.zero())
                return cv_status::timeout;

 for comparison, see
 libstdc++ does
(<a href="https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00818_source.html">https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00818_source.html</a>)
    template<typename _Lock, typename _Clock, typename _Duration>
        00217       cv_status
        00218       wait_until(_Lock& __lock,
        00219          const chrono::time_point<_Clock, _Duration>& __atime)
        00220       {
        00221         unique_lock<mutex> __my_lock(_M_mutex);
        00222         __lock.unlock();
        00223         cv_status __status = _M_cond.wait_until(__my_lock,
__atime);
        00224         __lock.lock();
        00225         return __status;
        00226       }

unconditionally unlock/lock (even if we are going to get a timeout).

This is IMPORTANT, because if you wait_for (0) a bunch of times (stupid but not
illegal). and in another thread try to get the mutex for the variable, before
setting it, you may infinite loop (because the 'signal'ing thread never gets
the lock).</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>