diff options
author | wrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68> | 2002-12-29 23:13:04 +0000 |
---|---|---|
committer | wrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68> | 2002-12-29 23:13:04 +0000 |
commit | 321ee705b1507152250bcbdd43fe63e9c6894bdc (patch) | |
tree | 6e14f6fc0b0ccdf9e234c58e0fc79e9098bc4262 /locks | |
parent | 6ef13e7432bac0614184a3f12c37f2d735edefe3 (diff) | |
download | libapr-321ee705b1507152250bcbdd43fe63e9c6894bdc.tar.gz |
Fix up code in thread_cond. First always escape the case where we outright
fail a single WaitForSingleObject(..., INFINITE) (yes, it can happen) and
properly unwind the *correct* error when we fail the nested Wait.
Also clean up the usage where rv is an apr result, and res in an NT result
to conform a bit better with other code.
Finally implements thread_cond_wait_with_timeout.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64238 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'locks')
-rw-r--r-- | locks/win32/thread_cond.c | 95 |
1 files changed, 72 insertions, 23 deletions
diff --git a/locks/win32/thread_cond.c b/locks/win32/thread_cond.c index 27cdb5100..e0c428f72 100644 --- a/locks/win32/thread_cond.c +++ b/locks/win32/thread_cond.c @@ -83,18 +83,23 @@ APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond, APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond, apr_thread_mutex_t *mutex) { - DWORD rv; + DWORD res; while (1) { - WaitForSingleObject(cond->mutex, INFINITE); + res = WaitForSingleObject(cond->mutex, INFINITE); + if (res != WAIT_OBJECT_0) { + return apr_get_os_error(); + } cond->num_waiting++; ReleaseMutex(cond->mutex); apr_thread_mutex_unlock(mutex); - rv = WaitForSingleObject(cond->event, INFINITE); + res = WaitForSingleObject(cond->event, INFINITE); cond->num_waiting--; - if (rv == WAIT_FAILED) { - return apr_get_os_error(); + if (res != WAIT_OBJECT_0) { + apr_status_t rv = apr_get_os_error(); + ReleaseMutex(cond->mutex); + return rv; } if (cond->signal_all) { if (cond->num_waiting == 0) { @@ -117,39 +122,83 @@ APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond, apr_thread_mutex_t *mutex, apr_interval_time_t timeout) { - /* Remember when implementing, timeout is usec, - * Win32 Wait functions take msec - */ - return APR_ENOTIMPL; + DWORD res; + DWORD timeout_ms = (DWORD) apr_time_as_msec(timeout); + + while (1) { + res = WaitForSingleObject(cond->mutex, timeout_ms); + if (res != WAIT_OBJECT_0) { + if (res == WAIT_ABANDONED) { + return APR_TIMEUP; + } + return apr_get_os_error(); + } + cond->num_waiting++; + ReleaseMutex(cond->mutex); + + apr_thread_mutex_unlock(mutex); + res = WaitForSingleObject(cond->event, timeout_ms); + cond->num_waiting--; + if (res != WAIT_OBJECT_0) { + apr_status_t rv = apr_get_os_error(); + ReleaseMutex(cond->mutex); + if (res == WAIT_ABANDONED) { + rv = APR_TIMEUP; + } + return rv; + } + if (cond->signal_all) { + if (cond->num_waiting == 0) { + ResetEvent(cond->event); + } + break; + } + if (cond->signalled) { + cond->signalled = 0; + ResetEvent(cond->event); + break; + } + ReleaseMutex(cond->mutex); + } + apr_thread_mutex_lock(mutex); + return APR_SUCCESS; } APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond) { - DWORD rv; + apr_status_t rv = APR_SUCCESS; + DWORD res; - WaitForSingleObject(cond->mutex, INFINITE); - cond->signalled = 1; - rv = SetEvent(cond->event); - ReleaseMutex(cond->mutex); - if (rv == 0) { + res = WaitForSingleObject(cond->mutex, INFINITE); + if (res != WAIT_OBJECT_0) { return apr_get_os_error(); } - return APR_SUCCESS; + cond->signalled = 1; + res = SetEvent(cond->event); + if (res == 0) { + rv = apr_get_os_error(); + } + ReleaseMutex(cond->mutex); + return rv; } APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond) { - DWORD rv; + apr_status_t rv = APR_SUCCESS; + DWORD res; - WaitForSingleObject(cond->mutex, INFINITE); + res = WaitForSingleObject(cond->mutex, INFINITE); + if (res != WAIT_OBJECT_0) { + return apr_get_os_error(); + } cond->signalled = 1; cond->signal_all = 1; - rv = SetEvent(cond->event); - ReleaseMutex(cond->mutex); - if (rv == 0) { - return apr_get_os_error(); + res = SetEvent(cond->event); + if (res == 0) { + rv = apr_get_os_error(); } - return APR_SUCCESS; + ReleaseMutex(cond->mutex); + return rv; } APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond) |