apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@apache.org
Subject cvs commit: apr/locks/win32 thread_cond.c
Date Tue, 18 Sep 2001 21:38:03 GMT
rbb         01/09/18 14:38:03

  Modified:    include/arch/win32 thread_cond.h
               locks/win32 thread_cond.c
  Log:
  An initial thread_condition variable implementation for Windows.
  This is kind of ugly, but I believe it works.  It does pass all of
  the APR tests, and I don't see any race conditions, but other
  eyes are more than welcome on this code now.
  
  Revision  Changes    Path
  1.2       +5 -0      apr/include/arch/win32/thread_cond.h
  
  Index: thread_cond.h
  ===================================================================
  RCS file: /home/cvs/apr/include/arch/win32/thread_cond.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- thread_cond.h	2001/09/13 01:04:23	1.1
  +++ thread_cond.h	2001/09/18 21:38:03	1.2
  @@ -59,6 +59,11 @@
   
   struct apr_thread_cond_t {
       apr_pool_t *pool;
  +    HANDLE event;
  +    HANDLE mutex;
  +    int signal_all;
  +    int num_waiting;
  +    int signalled;
   };
   
   #endif  /* THREAD_COND_H */
  
  
  
  1.2       +68 -5     apr/locks/win32/thread_cond.c
  
  Index: thread_cond.c
  ===================================================================
  RCS file: /home/cvs/apr/locks/win32/thread_cond.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- thread_cond.c	2001/09/13 01:04:23	1.1
  +++ thread_cond.c	2001/09/18 21:38:03	1.2
  @@ -60,29 +60,92 @@
   #include "win32/thread_cond.h"
   #include "apr_portable.h"
   
  +static apr_status_t thread_cond_cleanup(void *data)
  +{
  +    apr_thread_cond_t *cond = data;
  +    if (cond->num_waiting != 0) {
  +        printf("somebody's waiting, but I'm closing it anyway.\n");
  +    }
  +    CloseHandle(cond->mutex);
  +    CloseHandle(cond->event);
  +    return APR_SUCCESS;
  +}
  +
   APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
                                                    apr_pool_t *pool)
   {
  -    return APR_ENOTIMPL;
  +    *cond = apr_palloc(pool, sizeof(**cond));
  +    (*cond)->pool = pool;
  +    (*cond)->event = CreateEvent(NULL, TRUE, FALSE, NULL);
  +    (*cond)->mutex = CreateMutex(NULL, FALSE, NULL);
  +    (*cond)->signal_all = 0;
  +    (*cond)->num_waiting = 0;
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
                                                  apr_thread_mutex_t *mutex)
   {
  -    return APR_ENOTIMPL;
  +    DWORD rv;
  +
  +    while (1) {
  +        WaitForSingleObject(cond->mutex, INFINITE);
  +        cond->num_waiting++;
  +        ReleaseMutex(cond->mutex);
  +
  +        apr_thread_mutex_unlock(mutex);
  +        rv = WaitForSingleObject(cond->event, INFINITE);
  +        cond->num_waiting--;
  +        if (rv == WAIT_FAILED) {
  +            return apr_get_os_error();
  +        }
  +        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)
   {
  -    return APR_ENOTIMPL;
  +    DWORD rv;
  +
  +    WaitForSingleObject(cond->mutex, INFINITE);
  +    cond->signalled = 1;
  +    rv = SetEvent(cond->event);
  +    ReleaseMutex(cond->mutex);
  +    if (rv == 0) {
  +        return apr_get_os_error();
  +    }
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond)
   {
  -    return APR_ENOTIMPL;
  +    DWORD rv;
  +
  +    WaitForSingleObject(cond->mutex, INFINITE);
  +    cond->signalled = 1;
  +    cond->signal_all = 1;
  +    rv = SetEvent(cond->event);
  +    ReleaseMutex(cond->mutex);
  +    if (rv == 0) {
  +        return apr_get_os_error();
  +    }
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond)
   {
  -    return APR_ENOTIMPL;
  +    return apr_pool_cleanup_run(cond->pool, cond, thread_cond_cleanup);
   }
  
  
  

Mime
View raw message