const auto duration = Returns_10_seconds();
while(cv.wait_for(lock, duration) == std::cv_status::timeout);
This is definitely a wrong thing to do and thus does not make sense discussing how to fix it for the case of spurious wakeups, as it is broken even for the case of ordinary wakeups, because the wait condition is not re-examined after returning from the wait.
const auto duration = Returns_10_seconds();
while(!Predicate())
cv.wait_for(lock, duration);
Even after the edit, the answer stays the same: you can't really handle "spurious wakeups", because you can't really tell the reason for the wakeup - it may well be a completely legit wakeup due to a call to condition_variable::notifyXXX
before the timeout has expired.
First, note that you can't really distinguish between a wakeup caused by a call to condition_variable::notifyXXX
and wakeup caused by, for example, a POSIX signal[1].
Second, even if POSIX signals are not of concern, the waiting thread still must reexamine the condition as it is possible for the condition to change between the time the condition variable is signaled and the waiting thread returns from the condition wait.
What you really have to do is treat in a special manner not waking up before the timeout, but waking up due to timeout. And that entirely depends on the reasons to have a timeout in the first place, i.e. on the specifics of application/problem domain.
[1] if wait on a condition variable is interrupted by a signal, after executing the signal handler the thread is allowed either to resume wait or return