A Pitfall in C++ Condition Variable’s wait Method

I discovered a misconception in my previous understanding while looking at ThreadPool on GitHub.

Overloads of wait

The C++ condition variable’s related waiting methods wait, wait_for, and wait_until provide an overload that accepts a Predicate pred parameter:

1
2
template< class Predicate >
void wait( std::unique_lock<std::mutex>& lock, Predicate pred );

cppreference describes it as follows:

wait causes the current thread to block until the condition variable is notified or a spurious wakeup occurs. pred can be provided to detect spurious wakeups.

The above overload is equivalent to:

1
2
while (!pred())
    wait(lock);

Therefore, if pred is already true when the wait begins, the call exits immediately—even without a notification.

I previously believed this condition was only checked once at the moment of wakeup—that is, the thread would exit the wait only after being woken and the condition being satisfied simultaneously.

Although the program logic resulting from these two different interpretations is generally similar, this misconception could mislead the author into applying special handling to the blocking that occurs when the pred condition is already satisfied at the start of a wait.

Thoughts

C++ has so many subtle details. If the fundamentals are shaky, everything can come crashing down. There is still much to learn.

References