summaryrefslogtreecommitdiff
path: root/evthread_win32.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2010-08-30 11:35:06 -0400
committerNick Mathewson <nickm@torproject.org>2010-08-30 11:35:06 -0400
commitacc4aca49e246a46e03f8978517c9b3d23b1baea (patch)
tree18c26ee1f4b67f2fdb2cac8dcf285bd98d92dbb8 /evthread_win32.c
parentd61b2f33861eacdc0f9d343d38522fd91c1b7e72 (diff)
downloadlibevent-acc4aca49e246a46e03f8978517c9b3d23b1baea.tar.gz
Fix a bug in our win32 condition implementation
The do ... while loop in our wait code could spin while waiting because the event object wasn't reset until there were no longer any events waiting to be woken up. We also want to reset the event object if the count of events to wake up reaches zero. Found by Chris Davis. Fixes bug 3053358.
Diffstat (limited to 'evthread_win32.c')
-rw-r--r--evthread_win32.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/evthread_win32.c b/evthread_win32.c
index 795f410f..9bb35486 100644
--- a/evthread_win32.c
+++ b/evthread_win32.c
@@ -253,20 +253,30 @@ evthread_win32_cond_wait(void *_cond, void *_lock, const struct timeval *tv)
--cond->n_waiting;
result = 0;
waiting = 0;
+ goto out;
} else if (res != WAIT_OBJECT_0) {
result = (res==WAIT_TIMEOUT) ? 1 : -1;
--cond->n_waiting;
waiting = 0;
+ goto out;
} else if (ms != INFINITE) {
endTime = GetTickCount();
if (startTime + ms_orig <= endTime) {
result = 1; /* Timeout */
--cond->n_waiting;
waiting = 0;
+ goto out;
} else {
ms = startTime + ms_orig - endTime;
}
}
+ /* If we make it here, we are still waiting. */
+ if (cond->n_to_wake == 0) {
+ /* There is nobody else who should wake up; reset
+ * the event. */
+ ResetEvent(cond->event);
+ }
+ out:
LeaveCriticalSection(&cond->lock);
} while (waiting);