<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=http://email.email.llvm.org/c/eJylV8tu2zoQ_Rp5Q0SwJSexF16kTQp0X-AuDUqiLbYUqfJhx39_z5BS_Ihc3OIagm2J5DzOzJwZVaY5bX600jFcVijuRcO8YZw52UnFLZ67ILC057aRes-yp_mRS7_dGYu_WOiNpUNSs6woy-fF0xP-rHxrwr6FFF0L5lvBKtHygzTBMrO7FQLdrhe13MkkyAvbuct9QXupcJMVXyEsWUtCO2MF2wXd8E5oz1WyNivWeTZ_zeYv6fu7JkG10Y300ujtgVvJKyWy8gXXlQJ2bEXczSu39bITg3lKONLINTOWid8BqoASFr8qU_9KgrQ5wnEoHwzFDy3mQcc94xKJ08azmislGtrIdRMNPGyd5z64JI60m-CHE1b4YDXB03WikYiTOuUsRu6MbGPEINtoQNuRjQQTxAIiG5UdW1kjLvwU1VyglJVvbLFib7udqP3FIh5nb0W2mmfrJZxYrPIFHGEv3nSSfDhFTwDRra_Rr4ruEUvKjhcKXX5XbEFn_iH8g47HEjoX0i9k46c3zskK-uNmyk1oIXfTtnVKFohL2P1Bc0kSf7QxlWpKEXaUSo1mpJxwcq85AsaqE6qDjCJ0AbbcnbZGiyG-FM7bVdx9rJ5tEO-9tDxqQ6aT3cg5o4JHvaTQk5NlkRf5kuw7VwhZMKYn9CEjXR8sMsAhJ-46GYV8T5o-_BTv0jt2kBzBwk0tenpMUm8BR6KljGU9VFlyjw4T7JcSrwovpmetBLeIEmVD0Lyr5D5EUyktvYhl5e8WiwOPqIYBwyNSdotkvyicxEqxNgcID1yBrRJzXJRwzr7rRqRDY-0NZDZdotpb04RaJJpJmSaV9CeSreRBpP1UTgIUhPhjoxW8IZyk3kktqUKBoumHzJziMhSjQtxhEsRcSABO4KdIxPXvIG2i0A658U78aGwjYgRqMNI-Le4DoEB0IqjMBRR5BJbWjJV7qYmzkoYU9VQqps_ZNyK1d971iRMvSQF2pivdFiUIXYVGsKz8WrfWaINUm1ycoNvJjdGrO2vJ3vNi_A6OEEUmCdfzmtitSYyZ7NkiTMJyBQr7cnkMMWUdl3qIclp5HrYwfD7kJJwHu6Y2fPaN1YerrVnxDdcfDmy5Pt0eqoxRUGJ6uP7KdnBBXAv9bMkQUE9OPX7Jiqfs8XVkyEvfbg5JVMYALT1wSog-NuNiVThCp7w5-0nYlcCg5e8gtpEsh0JK6E1ISgcHH70NYkLX6_WD-pB_YtIrXHDg9tHHP0DvPOOBWuE8Kr3JlwECDzRO23qqnU8Lvo_v38CRGCAqWhAsk5EbQLigj2I1EtB_9IaIcNsbFMHYiqZDkxJ3VJZSYlQ1n0wN-sgdufC3wLKHFJI3tnR3_abPZ46eMoI-Pv9pPkr83qY0D7DFNAC32Xf14OpmUtnHjlvqPHfEgWrTWNdb4Wh29Wgq1Fw4nnH1oOSOOp0TQ4fh7Gjsr6sm0VuDBhXJkKMnIcupCXKHccvVrWgCNetdpHZRh9ju0Q-GMaKOQ4ajxphGROlDGkaSPh-_oSU1XmggyWRbc7oWOoxZkVtH6-L4lIYn7BUH2E35FIeFiZ4Wp6bUkK691PHoSQrVOMqwStQ8AJPbXjpsTKPinab-6a0AlfDsSKFv46QWJ5k0ikzzNSn6GLGdEHG-xuydPHFoSBQTbO6uFL0oF0dBkcQrWaFQ6qwAXX_BOI9MoJeX5H5trMX4fTHTA5c-AnIe4_NZsymbdbnmM_Baa-ym7YUzP2fBqk3rfR-n91jIe-nbUOW16XCj1GH8eYChP6EIt_GVCfX37bFcF6tZu3l6eqoeF7vdc7F4Xqwfm7WoKr6c491uLqp508wUr4Rym9hwCi2O41tXgeYz-_8WyE0xL3AtVotyuVqW-Zqv8Ld-hDllzR-X2XIukG0qJzm5sfuZ3USRVdg7LFItuPMidzS7CxENhoVeeiU2Ez38nFLjO9qI-MPwQhVrDXNsjWk5ZeI4C7pZ9GITXfgXAPzBDg>53928</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            condition_variable wait_until is not standard-conforming and can cause livelocks
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          hpesoj
      </td>
    </tr>
</table>

<pre>
    This is related to a similar issue regarding `wait_for` reported in #37166 (though since the behaviour of `wait_for` is specified in terms of `wait_until`, this is the more fundamental issue).

In `condition_variable::wait_until` when `abs_time` is less than or equal to `Clock::now()`, `lock.unlock()` is not called, and `cv_status::timeout` is returned immediately. This behaviour does not conform to the standard, which says:

> 18 Effects:
> —(18.1) Atomically calls lock.unlock() and blocks on *this.
> —(18.2) When unblocked, calls lock.lock() (possibly blocking on the lock), then returns.
> —(18.3) The function will unblock when signaled by a call to notify_one(), a call to notify_all(),
> expiration of the absolute timeout (32.2.4) specified by abs_time, or spuriously.
> —(18.4) If the function exits via an exception, lock.lock() is called prior to exiting the function.

This clearly and unambiguously states that `lock.unlock()` should _always_ be called, regardless of the value of `abs_time`. Indeed, not calling `lock.unlock()` introduces the possibility of livelock, where one thread is infinitely looping on `wait_until`, while another thread is unable to acquire the mutex in order to change the guarded state such that the original thread exits the loop. For example:

```
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>

using namespace std::chrono_literals;

int main()
{
    std::mutex mutex;
    std::condition_variable cv;
    //std::condition_variable_any cv;
    bool stop = false;
    
    std::thread t([&]() {
        std::this_thread::sleep_for(2s);
        {
            std::unique_lock lock(mutex);
            stop = true;
        }
        cv.notify_all();
    });
    
    const auto t0 = std::chrono::steady_clock::now();
    
    {
        std::unique_lock lock(mutex);
        while (!stop) {
            cv.wait_until(lock, std::chrono::steady_clock::time_point());
            //cv.wait_for(lock, 0s);
            if (std::chrono::steady_clock::now() - t0 > 4s) {
                lock.unlock();
                t.join();
                return 1;
            }
        }
    }
    t.join();
}
```

This example is representative of a real-life case where a worker thread is processing a list of tasks scheduled for execution at specific times. In the situation where there is always a task ready for execution, the main thread will block forever waiting to acquire the mutex, as the worker thread never yields (because `wait_until` never calls `lock.unlock()`).

It's worth noting that `condition_variable_any` does not seem to have the same problem.

Also note that libstdc++ implements the correct behaviour as per the standard.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyVV8tu2zoQ_Rp5Q0SwJSexF16kTQp0X-AuDUqiLbYUqfJhx39_z5BS_IhctIZgWyI5jzMzZ0aVaU6bH610DJcVinvRMG8YZ052UnGL5y4ILO25baTes-xpfuTSb3fG4i8WemPpkNQsK8ryefH0hD8r35qwbyFF14L5VrBKtPwgTbDM7G6FQLfrRS13Mgnywnbucl_QXircZMVXCEvWktDOWMF2QTe8E9pzlazNinWezV-z-Uv6_q5JUG10I700envgVvJKiax8wXWlgB1bEXfzym297MRgnhKONHLNjGXid4AqoITFr8rUv5IgbY5wHMoHQ_FDi3nQcc-4ROK08azmSomGNnLdRAMPW-e5Dy6JI-0m-OGEFT5YTfB0nWgk4qROOYuROyPbGDHINhrQdmQjwQSxgMhGZcdW1ogLP0U1Fyhl5RtbrNjbbidqf7GIx9lbka3m2XoJJxarfAFH2Is3nSQfTtETQHTra_SronvEkrLjhUKX3xVb0Jn_CP-g47GEzoX0C9n46Y1zsoL-uJlyE1rI3bRtnZIF4hJ2f9BcksQfbUylmlKEHaVSoxkpJ5zca46AseqE6iCjCF2ALXenrdFiiC-F83YVdx-rZxvEey8tj9qQ6WQ3cs6o4FEvKfTkZFnkRb4k-84VQhaM6Ql9yEjXB4sMcMiJu05GId-Tpg8_xbv0jh0kR7BwU4ueHpPUW8CRaCljWQ9VltyjwwT7pcSrwovpWSvBLaJE2RA07yq5D9FUSksvYln5u8XiwCOqYcDwiJTdItkvCiexUqzNAcIDV2CrxBwXJZyz77oR6dBYewOZTZeo9tY0oRaJZlKmSSX9iWQreRBpP5WTAAUh_thoBW8IJ6l3UkuqUKBo-iEzp7gMxagQd5gEMRcSgBP4KRJx_TtImyi0Q268Ez8a24gYgRqMtE-L-wAoEJ0IKnMBRR6BpTVj5V5q4qykIUU9lYrpc_aNSO2dd33ixEtSgJ3pSrdFCUJXoREsK7_WrTXaINUmFyfodnJj9OrOWrL3vBi_gyNEkUnC9bwmdmsSYyZ7tgiTsFyBwr5cHkNMWcelHqKcVp6HLQyfDzkJ58GuqQ2ffWP14WprVnzD9YcDW65Pt4cqYxSUmB6uv7IdXBDXQj9bMgTUk1OPX7LiKXt8HRny0rebQxKVMUBLD5wSoo_NuFgVjtApb85-EnYlMGj5O4htJMuhkBJ6E5LSwcFHb4OY0PV6_aA-5J-Y9AoXHLh99PEP0DvPeKBWOI9Kb_JlgMADjdO2nmrn04Lv4_svcCQGiIoWBMtk5AYQLuijWI0E9JfeEBFue4MiGFvRdGhS4o7KUkqMquaTqUEfuSMX_hVY9pBC8saW7q7f9PnM0VNG0MfnP81Hid_blOYBtpgG4Db7rh5c3Uwq-9hxS53njjhQbRrreiscza4eTYWaC8czrh6U3FGnc2LoMJwdjf111SR6a9CgIhly9CRkOTVB7jBuuboVTaBmvYvULuoQ2z36wTBG1HHIcNQY04gofUjDSNLn4ze0pMYLDSSZbGtO10KHMSty62hdHJ_S8IS94gC7KZ_isDDR0-LUlBrStZc6Hj1JoRpHGVaJmgdgcttLh41pVLzT1D-9FaASnh0p9G2c1OIkk0aRab4mRR8jthMizteYvZMnDg2JYoLN3ZWiF-XiKCiSeCUrFEqdFaDrLxjnkQn08pLcr421GL8vZnrg0kdAzmN8Pms2ZbMu13zmpVdiM9GPzvCM7xvj6Yfh5SDmDWayGpNfQnWca9wsWLVpve_ja0BkhL30bajy2nS4Ueow_jzA45-wGLfx3QuF_O2xXBerWbvZref185w_znfV_HEpqup5tZov-KpcFGKxLouZ4pVQbhM7V6HFcXx9K9DFZnJTzAtci9WiXK6WZb7mK_ytHxfP-OaPy2w5F0g6lZMdubH7md1Ek6qwd1ikknDnRe5ohBciqoN8tITW2E3bC2d-zqLmTbT8f54eqys">