Spurious wakeup is allowed by various platforms. To counter that, we write below looping mechanism:
while(ContinueWaiting())
cv.wait(lock); // cv is a `std::conditional_variable` object
Same thing is understandable for conditional_variable::wait_until()
.
But look at below example:
const auto duration = Returns_10_seconds();
while(!Predicate())
cv.wait_for(lock, duration);
Imagine that, spurious wakeup happened at 1 second. Timeout is not yet reached.
Will it wait for another 10 seconds? This would lead to infinite loop, which I am sure should not happen. From source code, internally wait_for()
calls wait_until()
.
I want to understand, how does wait_for()
deals with spurious wakeups?
I want to understand, how does
wait_for()
deals with spurious wakeups?
It doesn't.
This function is typically used in a situation where if you wake up spuriously, you want to do some other work anyway. And if you don't wake up spuriously, you want to force a "spurious" wake up by the time duration
has passed. This means it is not typically used in a loop as you show, for exactly the reasons you state. I.e. timeouts and spurious wake ups are treated identically.
Now you might be wondering, well, what does the predicate version do, as it implies a loop?
template <class Rep, class Period, class Predicate>
bool
wait_for(unique_lock<mutex>& lock, const chrono::duration<Rep, Period>& rel_time,
Predicate pred);
This is specified to have the same effects as:
return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
The wait_until
variation does distinguish between spurious wake ups and timeouts. It does so with a loop like this:
while (!pred())
if (wait_until(lock, abs_time) == cv_status::timeout)
return pred();
return true;