Subj : Re: Win32 condition variables redux To : comp.programming.threads From : Charles Bryant Date : Wed Aug 03 2005 11:38 pm In article <59GdnTUDgpKpuWzfRVn-2A@comcast.com>, Chris Thomasson <_no_damn_spam_cristom@_no_damn_comcast.net_spam> wrote: > >An event object per-thread and linked-lists for waitsets can create a >"fairly efficient" and correct condvar for windows. ... >Something like this: > > skip down to: >void condvar_broadcast( condvar_t *_this ) ... > LeaveCriticalSection( &_this->mutex ); > > while ( thread ) > { > next = thread->next; Note that at this point we don't hold any mutex while in: >void prv_condvar_pop( condvar_t *_this, per_thread_t *thread ) >{ ... > thread->next = 0; > thread->prev = 0; >} called from >int prv_condvar_timeout( condvar_t *_this, per_thread_t *thread ) >{ > int err = 0, wait = 0; > LONG count = 0; > EnterCriticalSection( &_this->mutex ); > if ( thread->state ) { > prv_condvar_pop( _this, thread ); So if a thread gets a timeout just as a condvar_broadcast() is running through the list of threads, then the thread may corrupt the list of threads to wake, leading to threads never being woken. To test, use this scenario: Modify the code to insert 'Sleep(10 seconds)' just after the LeaveCriticalSection in condvar_broadcast() Run the following: Start N threads which do condvar_timedwait() with no timeout. Sleep one second to ensure that they have gone asleep Start a thread which does condvar_timedwait() with a timeout of 4 seconds wait 1 second Start N threads which do condvar_timedwait() with no timeout. wait 1 second perform condvar_broadcast() wait 15 seconds check how many threads were woken. It should be 2N+1, but I believe it will be N+1 .