Artyom Chirkov
Artyom Chirkov

Reputation: 363

std::condition_variable wait_for infinite

I am trying to make an infinite wait on the condition variable with the following code (just a sample to display the issue):

std::condition_variable cond;
std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
cond.wait_for(lock, std::chrono::steady_clock::duration::max());

But the wait exits straight away. Digging a little deeper into the (MS) implementation of wait_for I've found that it actually uses wait_until function. But before that it converts the time using a call to chrono::system_clock::now() and just adding the duration.

And of course this leads to integer overflow so the new time becomes <= 'now'. Thus wait_until exits immediately. The same happens to all other timed wait functions (e.g. try_lock_for in std::timed_mutex class).

Summurazing the above, I would like to ask if this is a bug in the implementation of the timed wait functions and if so then where can I write about it?

Also, since wait_until uses system_clock, actual wait time should vary if there were time adjustments during the wait (because system_clock is not monotonic). Thus there is no trust to wait duration.

Upvotes: 3

Views: 2974

Answers (2)

lumpidu
lumpidu

Reputation: 759

A bit late, but maybe interesting for others: if you want to wait endlessly, simply do

std::condition_variable cond;
std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
cond.wait(lock);

But I'd additionally use a predicate condition because of spurious wakeups, as mentioned already in the comments above.

Upvotes: 0

Timmmm
Timmmm

Reputation: 97008

The cppreference documentation says:

Note that rel_time must be small enough not to overflow when added to std::chrono::steady_clock::now().

And:

The clock tied to timeout_time is used, which is not required to be a monotonic clock.There are no guarantees regarding the behavior of this function if the clock is adjusted discontinuously, but the existing implementations convert timeout_time from Clock to std::chrono::system_clock and delegate to POSIX pthread_cond_timedwait so that the wait honors ajustments to the system clock, but not to the the user-provided Clock. In any case, the function also may wait for longer than until after timeout_time has been reached due to scheduling or resource contention delays.

Even if the clock in use is std::chrono::steady_clock or another monotonic clock, a system clock adjustment may induce a spurious wakeup.

If you want an infinite timeout you can just do something like this (not tested):

wait_until(lock, std::chrono::sys_time::max());

Upvotes: 0

Related Questions