You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by jf...@yahoo.com on 2002/05/16 21:10:04 UTC

[PATCH] WIN32 implementations of apr_thread_cond_wait + apr_thread_cond_timedwait

--- apr/locks/win32/thread_cond.c	Wed Mar 13 15:39:22 2002
+++ apr_new/locks/win32/thread_cond.c	Thu May 16 14:27:03 2002
@@ -85,15 +85,20 @@
 {
     DWORD rv;
 
+    apr_thread_mutex_unlock(mutex);
     while (1) {
         WaitForSingleObject(cond->mutex, INFINITE);
         cond->num_waiting++;
         ReleaseMutex(cond->mutex);
 
-        apr_thread_mutex_unlock(mutex);
         rv = WaitForSingleObject(cond->event, INFINITE);
+
+        WaitForSingleObject(cond->mutex, INFINITE);
         cond->num_waiting--;
+        ReleaseMutex(cond->mutex);
+
         if (rv == WAIT_FAILED) {
+            apr_thread_mutex_lock(mutex);
             return apr_get_os_error();
         }
         if (cond->signal_all) {
@@ -107,7 +112,6 @@
             ResetEvent(cond->event);
             break;
         }
-        ReleaseMutex(cond->mutex);
     }
     apr_thread_mutex_lock(mutex);
     return APR_SUCCESS;
@@ -115,8 +119,51 @@
 
 APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond,
                                                     apr_thread_mutex_t *mutex,
-                                                    apr_interval_time_t timeout){
-    return APR_ENOTIMPL;
+                                                    apr_interval_time_t timeout)
+{
+    DWORD rv;
+    apr_time_t time_left = timeout;
+    apr_time_t time_begin = apr_time_now();
+
+	apr_thread_mutex_unlock(mutex);
+    while (1) {
+        WaitForSingleObject(cond->mutex, INFINITE);
+        cond->num_waiting++;
+        ReleaseMutex(cond->mutex);
+
+        time_left -= apr_time_now() - time_begin;
+        if (time_left < 0) {
+            time_left = 0;
+        }
+
+        rv = WaitForSingleObject(cond->event, (DWORD)(time_left / 1000));
+
+        WaitForSingleObject(cond->mutex, INFINITE);
+        cond->num_waiting--;
+        ReleaseMutex(cond->mutex);
+
+        if (rv == WAIT_FAILED) {
+            apr_thread_mutex_lock(mutex);
+            return apr_get_os_error();
+        }
+        if (rv == WAIT_TIMEOUT) {
+            apr_thread_mutex_lock(mutex);
+            return APR_TIMEUP;
+        }
+        if (cond->signal_all) {
+            if (cond->num_waiting == 0) {
+                ResetEvent(cond->event);
+            }
+            break;
+        }
+        if (cond->signalled) {
+            cond->signalled = 0;
+            ResetEvent(cond->event);
+            break;
+        }
+    }
+    apr_thread_mutex_lock(mutex);
+    return APR_SUCCESS;
 }
 
 APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond)


-----------------------------------------------------------------------------


1- In the WIN32 implementation of the apr_thread_cond_wait() function:
   - the decrement operation on cond->num_waiting was not guarded by cond->mutex;
   - on a WAIT_FAILED situation, the mutex was kept unlocked;
   - there were a useless release of cond->mutex at the end of the while loop.

2- I coded the WIN32 implementation of the apr_thread_cond_timedwait() function.
   There were none.
   I used the (new) apr_thread_cond_wait() function as a template.


Jean-Francois BRIERE