summaryrefslogtreecommitdiff
path: root/locks/os2
diff options
context:
space:
mode:
authorBrian Havard <bjh@apache.org>2002-02-11 12:56:13 +0000
committerBrian Havard <bjh@apache.org>2002-02-11 12:56:13 +0000
commit998750d4a2173fe6590533cb8efbdc0c803fcc3c (patch)
tree926f740a92d31449df9adc6ec5ea2c81fd761f5c /locks/os2
parent08ecbfccbc020b94cd58597946686251e79c1c11 (diff)
downloadapr-998750d4a2173fe6590533cb8efbdc0c803fcc3c.tar.gz
OS/2: Implement apr_proc_mutex*()
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@62942 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'locks/os2')
-rw-r--r--locks/os2/proc_mutex.c160
1 files changed, 152 insertions, 8 deletions
diff --git a/locks/os2/proc_mutex.c b/locks/os2/proc_mutex.c
index 82714c30d..f6b459801 100644
--- a/locks/os2/proc_mutex.c
+++ b/locks/os2/proc_mutex.c
@@ -59,56 +59,200 @@
#include "proc_mutex.h"
#include "fileio.h"
#include <string.h>
+#include <stddef.h>
+
+#define CurrentTid (*_threadid)
+
+static char *fixed_name(const char *fname, apr_pool_t *pool)
+{
+ char *semname;
+
+ if (fname == NULL)
+ semname = NULL;
+ else {
+ // Semaphores don't live in the file system, fix up the name
+ while (*fname == '/' || *fname == '\\') {
+ fname++;
+ }
+
+ semname = apr_pstrcat(pool, "/SEM32/", fname, NULL);
+
+ if (semname[8] == ':') {
+ semname[8] = '$';
+ }
+ }
+
+ return semname;
+}
+
+
+
+static apr_status_t proc_mutex_cleanup(void *vmutex)
+{
+ apr_proc_mutex_t *mutex = vmutex;
+ return apr_proc_mutex_destroy(mutex);
+}
+
+
APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
const char *fname,
apr_lockmech_e mech,
apr_pool_t *pool)
{
- return APR_ENOTIMPL;
+ apr_proc_mutex_t *new;
+ ULONG rc;
+ char *semname;
+
+ if (mech != APR_LOCK_DEFAULT) {
+ return APR_ENOTIMPL;
+ }
+
+ new = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
+ new->pool = pool;
+ new->owner = 0;
+ new->lock_count = 0;
+ *mutex = new;
+
+ semname = fixed_name(fname, pool);
+ rc = DosCreateMutexSem(semname, &(new->hMutex), DC_SEM_SHARED, FALSE);
+
+ if (!rc) {
+ apr_pool_cleanup_register(pool, new, proc_mutex_cleanup, apr_pool_cleanup_null);
+ }
+
+ return APR_FROM_OS_ERROR(rc);
}
+
+
APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
const char *fname,
apr_pool_t *pool)
{
- return APR_ENOTIMPL;
+ apr_proc_mutex_t *new;
+ ULONG rc;
+ char *semname;
+
+ new = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
+ new->pool = pool;
+ new->owner = 0;
+ new->lock_count = 0;
+
+ semname = fixed_name(fname, pool);
+ rc = DosOpenMutexSem(semname, &(new->hMutex));
+ *mutex = new;
+
+ if (!rc) {
+ apr_pool_cleanup_register(pool, new, proc_mutex_cleanup, apr_pool_cleanup_null);
+ }
+
+ return APR_FROM_OS_ERROR(rc);
}
-
+
+
+
APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex)
{
- return APR_ENOTIMPL;
+ ULONG rc = DosRequestMutexSem(mutex->hMutex, SEM_INDEFINITE_WAIT);
+
+ if (rc == 0) {
+ mutex->owner = CurrentTid;
+ mutex->lock_count++;
+ }
+
+ return APR_FROM_OS_ERROR(rc);
}
+
+
APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex)
{
- return APR_ENOTIMPL;
+ ULONG rc = DosRequestMutexSem(mutex->hMutex, SEM_IMMEDIATE_RETURN);
+
+ if (rc == 0) {
+ mutex->owner = CurrentTid;
+ mutex->lock_count++;
+ }
+
+ return APR_FROM_OS_ERROR(rc);
}
+
+
APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex)
{
- return APR_ENOTIMPL;
+ ULONG rc;
+
+ if (mutex->owner == CurrentTid && mutex->lock_count > 0) {
+ mutex->lock_count--;
+ rc = DosReleaseMutexSem(mutex->hMutex);
+ return APR_FROM_OS_ERROR(rc);
+ }
+
+ return APR_SUCCESS;
}
+
+
APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex)
{
- return APR_ENOTIMPL;
+ ULONG rc;
+ apr_status_t status = APR_SUCCESS;
+
+ if (mutex->owner == CurrentTid) {
+ while (mutex->lock_count > 0 && status == APR_SUCCESS) {
+ status = apr_proc_mutex_unlock(mutex);
+ }
+ }
+
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ if (mutex->hMutex == 0) {
+ return APR_SUCCESS;
+ }
+
+ rc = DosCloseMutexSem(mutex->hMutex);
+
+ if (!rc) {
+ mutex->hMutex = 0;
+ }
+
+ return APR_FROM_OS_ERROR(rc);
}
+
+
APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
+
+
/* Implement OS-specific accessors defined in apr_portable.h */
APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
apr_proc_mutex_t *pmutex)
{
+ *ospmutex = pmutex->hMutex;
return APR_ENOTIMPL;
}
+
+
APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
apr_os_proc_mutex_t *ospmutex,
apr_pool_t *pool)
{
- return APR_ENOTIMPL;
+ apr_proc_mutex_t *new;
+
+ new = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
+ new->pool = pool;
+ new->owner = 0;
+ new->lock_count = 0;
+ new->hMutex = *ospmutex;
+ *pmutex = new;
+
+ return APR_SUCCESS;
}