Ethouris
Ethouris

Reputation: 1901

What is the return value of `wait_until` in case of triggered or spurious wakeup, when timeout was reached?

I have a question for the "first" version of std::condition_variable::wait_until, that is, the one without the condition predicate parameter, which should return std::cv_status value.

The CV could be woken up on notify* call from another thread or spuriously, but then it tries to lock the mutex, and only then exits, and the absolute time at that point might have been reached. What is the return value in case when at the exit point the abs_time parameter value is already in the past in both these cases:

What I mean is: if the return value is no_timeout, could this have been caused by a spurious wakeup, which occasionally has woken up a thread at the edge of the timeout, making the function exit with having the time parameter already in the past? Or, in other words, should I re-check the time parameter myself after the function exits even if the returned value is no_timeout? NOTE: I trust the code that the interesting condition for me is always updated with notify_all() call (there are many various conditions actually and the waiting function can't really check them all).

Or more shortly: is a spurious wakeup a "fake timeout" or a "fake trigger"?

Upvotes: 1

Views: 39

Answers (1)

perivesta
perivesta

Reputation: 4031

It seems the standard doesn't explicitly specify this case, although in my opinion this does refer to the timeout being measured at the point in time where wait_until returns.

I've looked at the implementations of libstdc++ and libc++ and it seems both check the time argument last thing before returning, after the mutex is already locked again:

libc++

__do_timed_wait(__lk, __t_ns);
return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;

libstdc++

_M_cond.wait_until(*__lock.mutex(), CLOCK_MONOTONIC, __ts);
return (steady_clock::now() < __atime
        ? cv_status::no_timeout : cv_status::timeout);

Upvotes: 0

Related Questions