diff options
author | Robert Collins <rbtcollins@hotmail.com> | 2002-05-02 15:26:22 +0400 |
---|---|---|
committer | Robert Collins <rbtcollins@hotmail.com> | 2002-05-02 15:26:22 +0400 |
commit | 37143995da0e1b8e0a540034f244e58542b379df (patch) | |
tree | 894fd52d1c341a7a03883860d2d3a9a90e9aab8d /winsup/cygwin/thread.cc | |
parent | 4c956a7c0f8a9f1cb66abfb055c2ad24566032b5 (diff) |
2002-05-02 Robert Collins <rbtcollins@hotmail.com>
* 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.
Diffstat (limited to 'winsup/cygwin/thread.cc')
-rw-r--r-- | winsup/cygwin/thread.cc | 12 |
1 files changed, 7 insertions, 5 deletions
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); |