You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by bj...@apache.org on 2010/04/03 14:28:58 UTC
svn commit: r930508 - in /apr/apr/trunk:
include/arch/os2/apr_arch_thread_cond.h locks/os2/thread_cond.c
Author: bjh
Date: Sat Apr 3 12:28:52 2010
New Revision: 930508
URL: http://svn.apache.org/viewvc?rev=930508&view=rev
Log:
OS/2: Add an implementation of condition variables, derived from the Win32
implementation.
Modified:
apr/apr/trunk/include/arch/os2/apr_arch_thread_cond.h
apr/apr/trunk/locks/os2/thread_cond.c
Modified: apr/apr/trunk/include/arch/os2/apr_arch_thread_cond.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/arch/os2/apr_arch_thread_cond.h?rev=930508&r1=930507&r2=930508&view=diff
==============================================================================
--- apr/apr/trunk/include/arch/os2/apr_arch_thread_cond.h (original)
+++ apr/apr/trunk/include/arch/os2/apr_arch_thread_cond.h Sat Apr 3 12:28:52 2010
@@ -22,6 +22,11 @@
struct apr_thread_cond_t {
apr_pool_t *pool;
+ HEV semaphore;
+ HMTX mutex;
+ unsigned long num_waiting;
+ unsigned long num_wake;
+ unsigned long generation;
};
#endif /* THREAD_COND_H */
Modified: apr/apr/trunk/locks/os2/thread_cond.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/locks/os2/thread_cond.c?rev=930508&r1=930507&r2=930508&view=diff
==============================================================================
--- apr/apr/trunk/locks/os2/thread_cond.c (original)
+++ apr/apr/trunk/locks/os2/thread_cond.c Sat Apr 3 12:28:52 2010
@@ -23,38 +23,171 @@
#include "apr_arch_file_io.h"
#include <string.h>
+#ifndef DCE_POSTONE
+#define DCE_POSTONE 0x0800 // Post one flag
+#endif
+
+static apr_status_t thread_cond_cleanup(void *data)
+{
+ apr_thread_cond_t *cv = data;
+
+ if (cv->semaphore) {
+ DosCloseEventSem(cv->semaphore);
+ }
+
+ if (cv->mutex) {
+ DosCloseMutexSem(cv->mutex);
+ }
+
+ return APR_SUCCESS;
+}
+
+
+
APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
apr_pool_t *pool)
{
- return APR_ENOTIMPL;
+ int rc;
+ apr_thread_cond_t *cv;
+
+ cv = apr_pcalloc(pool, sizeof(**cond));
+ rc = DosCreateEventSem(NULL, &cv->semaphore, DCE_POSTONE, FALSE);
+
+ if (rc == 0) {
+ rc = DosCreateMutexSem(NULL, &cv->mutex, 0, FALSE);
+ }
+
+ *cond = cv;
+ cv->pool = pool;
+ apr_pool_cleanup_register(cv->pool, cv, thread_cond_cleanup,
+ apr_pool_cleanup_null);
+
+ return APR_FROM_OS_ERROR(rc);
+}
+
+
+
+static apr_status_t thread_cond_timedwait(apr_thread_cond_t *cond,
+ apr_thread_mutex_t *mutex,
+ ULONG timeout_ms )
+{
+ ULONG rc;
+ apr_status_t rv = APR_SUCCESS;
+ int wake = FALSE;
+ unsigned long generation;
+
+ DosRequestMutexSem(cond->mutex, SEM_INDEFINITE_WAIT);
+ cond->num_waiting++;
+ generation = cond->generation;
+ DosReleaseMutexSem(cond->mutex);
+
+ apr_thread_mutex_unlock(mutex);
+
+ do {
+ rc = DosWaitEventSem(cond->semaphore, timeout_ms);
+
+ DosRequestMutexSem(cond->mutex, SEM_INDEFINITE_WAIT);
+
+ if (cond->num_wake) {
+ if (cond->generation != generation) {
+ cond->num_wake--;
+ cond->num_waiting--;
+ rv = APR_SUCCESS;
+ break;
+ } else {
+ wake = TRUE;
+ }
+ }
+ else if (rc != 0) {
+ cond->num_waiting--;
+ rv = APR_TIMEUP;
+ break;
+ }
+
+ DosReleaseMutexSem(cond->mutex);
+
+ if (wake) {
+ wake = FALSE;
+ DosPostEventSem(cond->semaphore);
+ }
+ } while (1);
+
+ DosReleaseMutexSem(cond->mutex);
+ apr_thread_mutex_lock(mutex);
+ return rv;
}
+
+
APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
apr_thread_mutex_t *mutex)
{
- return APR_ENOTIMPL;
+ return thread_cond_timedwait(cond, mutex, SEM_INDEFINITE_WAIT);
}
+
+
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)
+{
+ ULONG timeout_ms = apr_time_as_msec(timeout);
+ return thread_cond_timedwait(cond, mutex, timeout_ms);
}
+
+
APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond)
{
- return APR_ENOTIMPL;
+ int wake = FALSE;
+
+ DosRequestMutexSem(cond->mutex, SEM_INDEFINITE_WAIT);
+
+ if (cond->num_waiting > cond->num_wake) {
+ wake = TRUE;
+ cond->num_wake++;
+ cond->generation++;
+ }
+
+ DosReleaseMutexSem(cond->mutex);
+
+ if (wake) {
+ DosPostEventSem(cond->semaphore);
+ }
+
+ return APR_SUCCESS;
}
+
+
APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond)
{
- return APR_ENOTIMPL;
+ unsigned long num_wake = 0;
+
+ DosRequestMutexSem(cond->mutex, SEM_INDEFINITE_WAIT);
+
+ if (cond->num_waiting > cond->num_wake) {
+ num_wake = cond->num_waiting - cond->num_wake;
+ cond->num_wake = cond->num_waiting;
+ cond->generation++;
+ }
+
+ DosReleaseMutexSem(cond->mutex);
+
+ for (; num_wake; num_wake--) {
+ DosPostEventSem(cond->semaphore);
+ }
+
+ 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);
}
-APR_POOL_IMPLEMENT_ACCESSOR(thread_cond)
+
+APR_POOL_IMPLEMENT_ACCESSOR(thread_cond)