summaryrefslogtreecommitdiff
path: root/locks
diff options
context:
space:
mode:
authorbjh <bjh@13f79535-47bb-0310-9956-ffa450edef68>2000-03-03 14:01:07 +0000
committerbjh <bjh@13f79535-47bb-0310-9956-ffa450edef68>2000-03-03 14:01:07 +0000
commit2741d0056bbe6df5492908abe89d69989bc9e201 (patch)
tree6423639310504e11b04b8617e2a8c0691d196789 /locks
parent9feb2ff157bd28a2096fc845c0765a691719d780 (diff)
downloadlibapr-2741d0056bbe6df5492908abe89d69989bc9e201.tar.gz
OS/2: Rework of mutex locks. Makes it safe to use the same object in multiple
threads while protecting against a moderately obscure problem where multiple handles to the same named mutex in the SAME THREAD behave as if they were the same handle. IE calling lock on one handle & unlock on another would result in the mutex not being owned by the thread. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@59680 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'locks')
-rw-r--r--locks/os2/locks.c72
-rw-r--r--locks/os2/locks.h6
2 files changed, 59 insertions, 19 deletions
diff --git a/locks/os2/locks.c b/locks/os2/locks.c
index 7b7a3f0d0..279c97801 100644
--- a/locks/os2/locks.c
+++ b/locks/os2/locks.c
@@ -61,8 +61,16 @@
#define INCL_DOS
#include <os2.h>
+#define CurrentTid (lock->tib->tib_ptib2->tib2_ultid)
-ap_status_t lock_cleanup(void *thelock)
+
+void setup_lock()
+{
+}
+
+
+
+static ap_status_t lock_cleanup(void *thelock)
{
struct lock_t *lock = thelock;
return ap_destroy_lock(lock);
@@ -75,12 +83,15 @@ ap_status_t ap_create_lock(struct lock_t **lock, ap_locktype_e type, ap_lockscop
struct lock_t *new;
ULONG rc;
char *semname;
+ PIB *ppib;
new = (struct lock_t *)ap_palloc(cont, sizeof(struct lock_t));
new->cntxt = cont;
new->type = type;
- new->curr_locked = 0;
+ new->owner = 0;
+ new->lock_count = 0;
new->fname = ap_pstrdup(cont, fname);
+ DosGetInfoBlocks(&(new->tib), &ppib);
if (fname == NULL)
semname = NULL;
@@ -89,6 +100,33 @@ ap_status_t ap_create_lock(struct lock_t **lock, ap_locktype_e type, ap_lockscop
rc = DosCreateMutexSem(semname, &(new->hMutex), type == APR_CROSS_PROCESS ? DC_SEM_SHARED : 0, FALSE);
*lock = new;
+
+ if (!rc)
+ ap_register_cleanup(cont, new, lock_cleanup, ap_null_cleanup);
+
+ return os2errno(rc);
+}
+
+
+
+ap_status_t ap_child_init_lock(ap_lock_t **lock, char *fname, ap_context_t *cont)
+{
+ int rc;
+ PIB *ppib;
+
+ *lock = (struct lock_t *)ap_palloc(cont, sizeof(struct lock_t));
+
+ if (lock == NULL)
+ return APR_ENOMEM;
+
+ DosGetInfoBlocks(&((*lock)->tib), &ppib);
+ (*lock)->owner = 0;
+ (*lock)->lock_count = 0;
+ rc = DosOpenMutexSem( fname, &(*lock)->hMutex );
+
+ if (!rc)
+ ap_register_cleanup(cont, *lock, lock_cleanup, ap_null_cleanup);
+
return os2errno(rc);
}
@@ -98,16 +136,14 @@ ap_status_t ap_lock(struct lock_t *lock)
{
ULONG rc;
- if (!lock->curr_locked) {
- rc = DosRequestMutexSem(lock->hMutex, SEM_INDEFINITE_WAIT);
-
- if (rc == 0)
- lock->curr_locked = TRUE;
+ rc = DosRequestMutexSem(lock->hMutex, SEM_INDEFINITE_WAIT);
- return os2errno(rc);
+ if (rc == 0) {
+ lock->owner = CurrentTid;
+ lock->lock_count++;
}
-
- return APR_SUCCESS;
+
+ return os2errno(rc);
}
@@ -116,12 +152,9 @@ ap_status_t ap_unlock(struct lock_t *lock)
{
ULONG rc;
- if (lock->curr_locked) {
+ if (lock->owner == CurrentTid && lock->lock_count > 0) {
+ lock->lock_count--;
rc = DosReleaseMutexSem(lock->hMutex);
-
- if (rc == 0)
- lock->curr_locked = FALSE;
-
return os2errno(rc);
}
@@ -133,10 +166,13 @@ ap_status_t ap_unlock(struct lock_t *lock)
ap_status_t ap_destroy_lock(struct lock_t *lock)
{
ULONG rc;
- ap_status_t stat;
+ ap_status_t stat = APR_SUCCESS;
+
+ if (lock->owner == CurrentTid) {
+ while (lock->lock_count > 0 && stat == APR_SUCCESS)
+ stat = ap_unlock(lock);
+ }
- stat = ap_unlock(lock);
-
if (stat != APR_SUCCESS)
return stat;
diff --git a/locks/os2/locks.h b/locks/os2/locks.h
index 86c304d1d..dd4244586 100644
--- a/locks/os2/locks.h
+++ b/locks/os2/locks.h
@@ -63,10 +63,14 @@
struct lock_t {
ap_context_t *cntxt;
ap_locktype_e type;
- int curr_locked;
char *fname;
HMTX hMutex;
+ TID owner;
+ int lock_count;
+ TIB *tib;
};
+void setup_lock();
+
#endif /* LOCKS_H */