STL icon indicating copy to clipboard operation
STL copied to clipboard

LWG-4301 `condition_variable{_any}::wait_{for, until}` should take timeout by value

Open StephanTLavavej opened this issue 2 months ago • 1 comments

LWG-4301 condition_variable{_any}::wait_{for, until} should take timeout by value

StephanTLavavej avatar Nov 13 '25 18:11 StephanTLavavej

Hi, I am working on this.

The change is minimal and obvious; however, I am having a bit of trouble with the test suite. I am extending tests\std\tests\GH_000685_condition_variable_any, checking all 10 overloads influenced by this change, but at first I couldn't get the tests to fail. After some research, I believe I have identified a slight inconsistency between the standard and the current implementation.

Compare

// in condition_variable in <mutex>
    template <class _Clock, class _Duration>
    cv_status wait_until(unique_lock<mutex>& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time) {
        // ...
        for (;;) {
            const auto _Now = _Clock::now();
            if (_Abs_time <= _Now) {
                return cv_status::timeout;
            }

            const unsigned long _Rel_ms_count = _Clamped_rel_time_ms_count(_Abs_time - _Now)._Count;

            const _Thrd_result _Res = _Cnd_timedwait_for_unchecked(_Mycnd(), _Lck.mutex()->_Mymtx(), _Rel_ms_count);
            if (_Res == _Thrd_result::_Success) {
                return cv_status::no_timeout; // But what if _Abs_time <= _Now already?
            }
        }
    }

with https://eel.is/c++draft/thread.condition.condvar#20

Returns: cv_status​::​timeout if the absolute timeout ([thread.req.timing]) specified by abs_time expired, otherwise cv_status​::​no_timeout.

When the _Abs_time is modified externally (which is what this LWG issue aims to prevent, so I am trying to trigger it with tests first), its new value is not taken into account until the next iteration of the for (;;) loop. If the condition variable is (in quick succession) notified and its timeout elapses, the function incorrectly returns that no timeout occurred.

Is this something to worry about?

Edit: Maybe https://eel.is/c++draft/thread.req.timing#2 is relevant as it acknowledges that there are inherent unpredictable delays around detection of timeouts, so attempts at "exact" time_point arithmetic are futile 🤔? Either way, I will look for an alternative method of testing this to get the PR out ASAP.

vmichal avatar Nov 19 '25 18:11 vmichal