Opened 14 years ago

Closed 14 years ago

#1950 closed Bugs (invalid)

pthread/condition_variable::wait() unlocks associated mutex prematurely and may miss a notification

Reported by: Stas Maximov <smaximov@…> Owned by: Anthony Williams
Milestone: Boost 1.36.0 Component: thread
Version: Boost 1.35.0 Severity: Showstopper
Keywords: pthread_cond_wait condition variable pthread mutex Cc:

Description

pthread implementation of class condition_variable implements wait() is as follows:

template<typename lock_type> void wait(lock_type& m) {

int res=0; {

detail::interruption_checker check_for_interruption(&cond); {

boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); m.unlock(); res=pthread_cond_wait(&cond,&internal_mutex);

} m.lock();

} if(res) {

throw condition_error();

}

}

Each condition variable must have an associated mutex. pthread_cond_wait() must enter with the mutex locked. Having the mutex locked guarantees that no notifications will be missed by the receiving thread.

The above implementation releases mutex before entering pthread_cond_wait(). This creates an opportunity for pre-emption of the thread just after the mutex was unlocked, but before pthread has been entered. If another thread pre-empts at this point and tries to notify this condition variable, this notification will be missed by this thread.

Substitution of some random, unrelated mutex into pthread_cond_wait() is not a solution. It is the original mutex that is associated with the condition that must be passed to pthread_cond_wait().

Change History (1)

comment:1 by Anthony Williams, 14 years ago

Resolution: invalid
Status: newclosed

Note that the same internal mutex is locked in both notify_one and notify_all. It is not possible to call pthread_cond_signal or pthread_cond_broadcast through the boost::condition_variable_any interface whilst a waiting thread is in the gap you highlighted.

Note: See TracTickets for help on using tickets.