I was reading through my STL implementation (standard-issue g++ 4.6.2
) and came across this bit of race condition inside of condition_variable
:
template<typename _Rep, typename _Period>
cv_status
wait_for(unique_lock<mutex>& __lock,
const chrono::duration<_Rep, _Period>& __rtime)
{
return wait_until(__lock, __clock_t::now() + __rtime);
}
Because __clock_t
is an std::chrono::system_clock
, we are tied to the whims of things like NTP (if the clock is moved back by a day after __clock_t::now() + __rtime
, then we'll wait for a day).
The C++ standard (30.5.1) appears to get it right:
26
Effects: as if
return wait_until(lock, chrono::steady_clock::now() + rel_time);
Boost's condition_variable
implementation has the same problem:
template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
{
return timed_wait(m,get_system_time()+wait_duration);
}
In fact, the underlying pthreads implementation seems to be the problem:
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
because abstime
is specified as "system time," not a monotonic clock.
So my question is: How would one implement something like std::condition_variable::wait_for
correctly? Is there an existing implementation that gets this right? Or am I missing something?