Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <rbtcollins@hotmail.com>2002-05-02 15:26:22 +0400
committerRobert Collins <rbtcollins@hotmail.com>2002-05-02 15:26:22 +0400
commit37143995da0e1b8e0a540034f244e58542b379df (patch)
tree894fd52d1c341a7a03883860d2d3a9a90e9aab8d /winsup/cygwin/thread.cc
parent4c956a7c0f8a9f1cb66abfb055c2ad24566032b5 (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.cc12
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);