diff options
author | bjh <bjh@13f79535-47bb-0310-9956-ffa450edef68> | 2000-03-03 14:01:07 +0000 |
---|---|---|
committer | bjh <bjh@13f79535-47bb-0310-9956-ffa450edef68> | 2000-03-03 14:01:07 +0000 |
commit | 2741d0056bbe6df5492908abe89d69989bc9e201 (patch) | |
tree | 6423639310504e11b04b8617e2a8c0691d196789 /locks | |
parent | 9feb2ff157bd28a2096fc845c0765a691719d780 (diff) | |
download | libapr-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.c | 72 | ||||
-rw-r--r-- | locks/os2/locks.h | 6 |
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 */ |