summaryrefslogtreecommitdiff
path: root/locks
diff options
context:
space:
mode:
authorwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2002-12-29 23:13:04 +0000
committerwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2002-12-29 23:13:04 +0000
commit321ee705b1507152250bcbdd43fe63e9c6894bdc (patch)
tree6e14f6fc0b0ccdf9e234c58e0fc79e9098bc4262 /locks
parent6ef13e7432bac0614184a3f12c37f2d735edefe3 (diff)
downloadlibapr-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.c95
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)