diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d5fea8fab..356a9ef14 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2002-05-02 Robert Collins + + * thread.cc (__pthread_cond_dowait): Fix a race on signalling from a + thread woken by the same condition variable it's signalling on. Thanks + to Michael Beach for the report and test case. + 2002-05-02 Christopher Faylor * path.h (pathconv_arg): Add PC_POSIX. @@ -44,6 +50,7 @@ Wed May 1 16:06:02 2002 Jason Tishler * include/cygwin/types.h: Include . +>>>>>>> 1.1179 Wed Apr 17 11:27:04 2002 Jason Tishler * security.cc (get_lsa_srv_inf): Prevent extraneous backslashes for diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 5c44ca90a..7ee5714e9 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -1791,20 +1791,22 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex, InterlockedIncrement (&((*themutex)->condwaits)); if (pthread_mutex_unlock (&(*cond)->cond_access)) system_printf ("Failed to unlock condition variable access mutex, this %p", *cond); + /* At this point calls to Signal will progress evebn if we aren' yet waiting + * However, the loop there should allow us to get scheduled and call wait, + * and have them call PulseEvent again if we dont' respond. + */ rv = (*cond)->TimedWait (waitlength); /* this may allow a race on the mutex acquisition and waits.. * But doing this within the cond access mutex creates a different race */ - bool last = false; - if (InterlockedDecrement (&((*cond)->waiting)) == 0) - last = true; + InterlockedDecrement (&((*cond)->waiting)); /* Tell Signal that we have been released */ InterlockedDecrement (&((*cond)->ExitingWait)); (*themutex)->Lock (); - if (last == true) - (*cond)->mutex = NULL; if (pthread_mutex_lock (&(*cond)->cond_access)) system_printf ("Failed to lock condition variable access mutex, this %p", *cond); + if ((*cond)->waiting == 0) + (*cond)->mutex = NULL; InterlockedDecrement (&((*themutex)->condwaits)); if (pthread_mutex_unlock (&(*cond)->cond_access)) system_printf ("Failed to unlock condition variable access mutex, this %p", *cond);