Hi,

as already said here
http://mail-archives.apache.org/mod_mbox/apr-dev/201404.mbox/%3CCAKQ1sVOQ9ydgvNsDzj14=TPfbPQUg_fCZOGW=hmojpuw4cl...@mail.gmail.com%3E
(which may have been lost in the atlantic ocean since it was quite out
of topic), the current apr_os_proc_mutex_get/set() implementation does
not do the right thing nor allow very much about posix semaphores wrt
these functions.

The attached patch tries to address this by adding the native type
field (sem_t*) in apr_os_proc_mutex_t so that it can be got or put by
the caller explicitely (previously it was stored in a int/fd in the OS
type whereas the sem_t* was used only by the apr_proc_mutex_*()
functions).
This is abviously an ABI change since apr_os_proc_mutex_t is defined
in include/apr_portable.h, I don't think we can avoid this.

Rather than also adding this new field to the unixes specific
apr_proc_mutex_t struct, I also modified the latter to replace all the
duplicated fields by a apr_os_proc_mutex_t member (called os). Since
apr_proc_mutex_t is private (include/arch/unix/apr_arch_proc_mutex.h
for unixes), this is not an API/ABI change.
This change implies the use of mutex->os.[native] instead of
mutex->[native] in the different mechanisms implementation, but it
also greatly simplifies apr_os_proc_mutex_get() to something as simple
as *osmutex = mutex->os.

To help disambiguate the mechanism to be used when creating an
apr_proc_mutex_t from a native type, I also added the new
apr_os_proc_mutex_put_ex() function, which takes the lockmech as
parameter, and allows then for example to create a APR_LOCK_FLOCK
mutex from a fd when the default lockmech is SYSV (both using a fd as
native type).
This, I think, addresses the showstopper from
http://svn.apache.org/viewvc?view=revision&revision=1587066.
To initialize the apr_proc_mutex_t from the native type, I slightly
modified the existing/private proc_mutex_choose_method() function to
eventually take an os type as argument and do the right thing when not
NULL.
This function is of course also implemented in other platforms (where
APR_LOCK_DEFAULT is to be used as lockmech since there is the only
choice on non-unixes), so this is a another API addon (still in
include/apr_portable.h).

On OS2, I have made apr_os_proc_mutex_get() return APR_SUCCESS since
the existing code looks correct (but the returned status), and
apr_os_proc_mutex_set() return APR_ENOPOOL when a NULL pool is given,
for consistency with other platforms.

For consistency on all platforms still, in the unix code this time, I
changed the behaviour of the proc_mutex_*_cleanup() functions so that
they cleanup the native mutex even if the APR mutex was created by
apr_os_proc_mutex_set(), taking care of not closing the fd twice (for
proc mutexes using a fd, since the mutex is also mapped to an
apr_file_t).
This is however inconsistant with other APR types that can be created
from a native type (eg. apr_os_file_t using apr_os_file_put(), quite
logically since the object is not really owned by APR), so maybe I
should have done the opposite on non-unix platforms, let me know...

Finally, netware, where the native mutex type is NXMutex_t (and not a
*pointer to* NXMutex_t).
AFAICT (from netware sources in nks/synch.h), the NXMutex_t struct is
defined as :

typedef struct
{
   uint64_t  reserved1;
   void     *reserved2[10];
} NXMutex_t;

This is hence impossible to get/set it via the
apr_os_proc_mutex_get/set() interface (would require a copy of the
struct, which is obviously not suitable).
The proposed change is to typedef NXMutex_t *apr_os_proc_mutex_t
instead (with the *pointer to*), and do the right thing in the get/set
functions.
That's another API/ABI change though, but I doubt anyone has already
used netware native mutex type successfully from/to
apr_proc_mutex_t...
Since I can't test it, this change is also attached here but in a
distinct patch, and it will probably require a review from someone who
knows netware and can test it (I don't, for both).

Thanks for your feedbacks (and sorry for this long message).

Regards,
Yann.
Index: include/apr_portable.h
===================================================================
--- include/apr_portable.h	(revision 1620587)
+++ include/apr_portable.h	(working copy)
@@ -46,6 +46,9 @@
 #if APR_HAVE_PTHREAD_H
 #include <pthread.h>
 #endif
+#if APR_HAVE_SEMAPHORE_H
+#include <semaphore.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -140,6 +143,10 @@ struct apr_os_proc_mutex_t {
     pthread_mutex_t *intraproc;
 #endif
 #endif
+#if APR_HAS_POSIXSEM_SERIALIZE
+    /** Value used for POSIX semaphores serialization */
+    sem_t *psem_interproc;
+#endif
 };
 
 typedef int                   apr_os_file_t;        /**< native file */
@@ -416,6 +423,21 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(ap
                                                 apr_pool_t *cont); 
 
 /**
+ * Convert the proc mutex from os specific type to apr type with the specified
+ * mechanism.
+ * @param pmutex The apr proc mutex we are converting to.
+ * @param ospmutex The os specific proc mutex to convert.
+ * @param mech The apr mutex locking mechanism
+ * @param cont The pool to use if it is needed.
+ * @remark Allows for disambiguation for platforms with multiple mechanisms
+ *         available.
+ */
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_put_ex(apr_proc_mutex_t **pmutex,
+                                                apr_os_proc_mutex_t *ospmutex,
+                                                apr_lockmech_e mech,
+                                                apr_pool_t *cont); 
+
+/**
  * Put the imploded time in the APR format.
  * @param aprtime the APR time format
  * @param ostime the time to convert
Index: include/arch/unix/apr_arch_proc_mutex.h
===================================================================
--- include/arch/unix/apr_arch_proc_mutex.h	(revision 1620587)
+++ include/arch/unix/apr_arch_proc_mutex.h	(working copy)
@@ -62,9 +62,6 @@
 #if APR_HAVE_PTHREAD_H
 #include <pthread.h>
 #endif
-#if APR_HAVE_SEMAPHORE_H
-#include <semaphore.h>
-#endif
 /* End System Headers */
 
 struct apr_proc_mutex_unix_lock_methods_t {
@@ -97,15 +94,11 @@ struct apr_proc_mutex_t {
     const apr_proc_mutex_unix_lock_methods_t *inter_meth;
     int curr_locked;
     char *fname;
-#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
+    apr_os_proc_mutex_t os;
+#if APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
     apr_file_t *interproc;
+    int closed_by_interproc;
 #endif
-#if APR_HAS_POSIXSEM_SERIALIZE
-    sem_t *psem_interproc;
-#endif
-#if APR_HAS_PROC_PTHREAD_SERIALIZE
-    pthread_mutex_t *pthread_interproc;
-#endif
 };
 
 void apr_proc_mutex_unix_setup_lock(void);
Index: locks/win32/proc_mutex.c
===================================================================
--- locks/win32/proc_mutex.c	(revision 1620587)
+++ locks/win32/proc_mutex.c	(working copy)
@@ -212,13 +212,17 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(ap
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_put_ex(apr_proc_mutex_t **pmutex,
                                                 apr_os_proc_mutex_t *ospmutex,
+                                                apr_lockmech_e mech,
                                                 apr_pool_t *pool)
 {
     if (pool == NULL) {
         return APR_ENOPOOL;
     }
+    if (mech != APR_LOCK_DEFAULT) {
+        return APR_ENOTIMPL;
+    }
     if ((*pmutex) == NULL) {
         (*pmutex) = (apr_proc_mutex_t *)apr_palloc(pool,
                                                    sizeof(apr_proc_mutex_t));
@@ -228,3 +232,10 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(ap
     return APR_SUCCESS;
 }
 
+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_os_proc_mutex_put_ex(pmutex, ospmutex, APR_LOCK_DEFAULT, pool);
+}
+
Index: locks/os2/proc_mutex.c
===================================================================
--- locks/os2/proc_mutex.c	(revision 1620587)
+++ locks/os2/proc_mutex.c	(working copy)
@@ -211,16 +211,23 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(ap
                                                 apr_proc_mutex_t *pmutex)
 {
     *ospmutex = pmutex->hMutex;
-    return APR_ENOTIMPL;
+    return APR_SUCCESS;
 }
 
 
 
-APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_put_ex(apr_proc_mutex_t **pmutex,
                                                 apr_os_proc_mutex_t *ospmutex,
+                                                apr_lockmech_e mech,
                                                 apr_pool_t *pool)
 {
     apr_proc_mutex_t *new;
+    if (pool == NULL) {
+        return APR_ENOPOOL;
+    }
+    if (mech != APR_LOCK_DEFAULT) {
+        return APR_ENOTIMPL;
+    }
 
     new = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
     new->pool       = pool;
@@ -232,3 +239,10 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(ap
     return APR_SUCCESS;
 }
 
+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_os_proc_mutex_put_ex(pmutex, ospmutex, APR_LOCK_DEFAULT, pool);
+}
+
Index: locks/unix/proc_mutex.c
===================================================================
--- locks/unix/proc_mutex.c	(revision 1620587)
+++ locks/unix/proc_mutex.c	(working copy)
@@ -45,7 +45,6 @@ static apr_status_t proc_mutex_no_perms_set(apr_pr
 }
 #endif    
 
-
 #if APR_HAS_POSIXSEM_SERIALIZE
 
 #ifndef SEM_FAILED
@@ -56,7 +55,7 @@ static apr_status_t proc_mutex_posix_cleanup(void
 {
     apr_proc_mutex_t *mutex = mutex_;
     
-    if (sem_close(mutex->psem_interproc) < 0) {
+    if (sem_close(mutex->os.psem_interproc) < 0) {
         return errno;
     }
 
@@ -71,8 +70,6 @@ static apr_status_t proc_mutex_posix_create(apr_pr
     sem_t *psem;
     char semname[APR_MD5_DIGESTSIZE * 2 + 2];
     
-    new_mutex->interproc = apr_palloc(new_mutex->pool,
-                                      sizeof(*new_mutex->interproc));
     /*
      * This bogusness is to follow what appears to be the
      * lowest common denominator in Posix semaphore naming:
@@ -135,7 +132,7 @@ static apr_status_t proc_mutex_posix_create(apr_pr
     }
     /* Ahhh. The joys of Posix sems. Predelete it... */
     sem_unlink(semname);
-    new_mutex->psem_interproc = psem;
+    new_mutex->os.psem_interproc = psem;
     new_mutex->fname = apr_pstrdup(new_mutex->pool, semname);
     apr_pool_cleanup_register(new_mutex->pool, (void *)new_mutex,
                               apr_proc_mutex_cleanup, 
@@ -148,7 +145,7 @@ static apr_status_t proc_mutex_posix_acquire(apr_p
     int rc;
 
     do {
-        rc = sem_wait(mutex->psem_interproc);
+        rc = sem_wait(mutex->os.psem_interproc);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         return errno;
@@ -162,7 +159,7 @@ static apr_status_t proc_mutex_posix_tryacquire(ap
     int rc;
 
     do {
-        rc = sem_trywait(mutex->psem_interproc);
+        rc = sem_trywait(mutex->os.psem_interproc);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         if (errno == EAGAIN) {
@@ -177,7 +174,7 @@ static apr_status_t proc_mutex_posix_tryacquire(ap
 static apr_status_t proc_mutex_posix_release(apr_proc_mutex_t *mutex)
 {
     mutex->curr_locked = 0;
-    if (sem_post(mutex->psem_interproc) < 0) {
+    if (sem_post(mutex->os.psem_interproc) < 0) {
         /* any failure is probably fatal, so no big deal to leave
          * ->curr_locked at 0. */
         return errno;
@@ -228,9 +225,9 @@ static apr_status_t proc_mutex_sysv_cleanup(void *
     apr_proc_mutex_t *mutex=mutex_;
     union semun ick;
     
-    if (mutex->interproc->filedes != -1) {
+    if (mutex->os.crossproc != -1) {
         ick.val = 0;
-        semctl(mutex->interproc->filedes, 0, IPC_RMID, ick);
+        semctl(mutex->os.crossproc, 0, IPC_RMID, ick);
     }
     return APR_SUCCESS;
 }    
@@ -241,18 +238,17 @@ static apr_status_t proc_mutex_sysv_create(apr_pro
     union semun ick;
     apr_status_t rv;
     
-    new_mutex->interproc = apr_palloc(new_mutex->pool, sizeof(*new_mutex->interproc));
-    new_mutex->interproc->filedes = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
-
-    if (new_mutex->interproc->filedes < 0) {
+    new_mutex->os.crossproc = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
+    if (new_mutex->os.crossproc == -1) {
         rv = errno;
         proc_mutex_sysv_cleanup(new_mutex);
         return rv;
     }
     ick.val = 1;
-    if (semctl(new_mutex->interproc->filedes, 0, SETVAL, ick) < 0) {
+    if (semctl(new_mutex->os.crossproc, 0, SETVAL, ick) < 0) {
         rv = errno;
         proc_mutex_sysv_cleanup(new_mutex);
+        new_mutex->os.crossproc = -1;
         return rv;
     }
     new_mutex->curr_locked = 0;
@@ -267,7 +263,7 @@ static apr_status_t proc_mutex_sysv_acquire(apr_pr
     int rc;
 
     do {
-        rc = semop(mutex->interproc->filedes, &proc_mutex_op_on, 1);
+        rc = semop(mutex->os.crossproc, &proc_mutex_op_on, 1);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         return errno;
@@ -281,7 +277,7 @@ static apr_status_t proc_mutex_sysv_tryacquire(apr
     int rc;
 
     do {
-        rc = semop(mutex->interproc->filedes, &proc_mutex_op_try, 1);
+        rc = semop(mutex->os.crossproc, &proc_mutex_op_try, 1);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         if (errno == EAGAIN) {
@@ -299,7 +295,7 @@ static apr_status_t proc_mutex_sysv_release(apr_pr
 
     mutex->curr_locked = 0;
     do {
-        rc = semop(mutex->interproc->filedes, &proc_mutex_op_off, 1);
+        rc = semop(mutex->os.crossproc, &proc_mutex_op_off, 1);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         return errno;
@@ -319,7 +315,7 @@ static apr_status_t proc_mutex_sysv_perms_set(apr_
     buf.sem_perm.gid = gid;
     buf.sem_perm.mode = apr_unix_perms2mode(perms);
     ick.buf = &buf;
-    if (semctl(mutex->interproc->filedes, 0, IPC_SET, ick) < 0) {
+    if (semctl(mutex->os.crossproc, 0, IPC_SET, ick) < 0) {
         return errno;
     }
     return APR_SUCCESS;
@@ -352,7 +348,7 @@ static apr_status_t proc_mutex_proc_pthread_cleanu
     apr_status_t rv;
 
     if (mutex->curr_locked == 1) {
-        if ((rv = pthread_mutex_unlock(mutex->pthread_interproc))) {
+        if ((rv = pthread_mutex_unlock(mutex->os.pthread_interproc))) {
 #ifdef HAVE_ZOS_PTHREADS
             rv = errno;
 #endif
@@ -361,14 +357,14 @@ static apr_status_t proc_mutex_proc_pthread_cleanu
     }
     /* curr_locked is set to -1 until the mutex has been created */
     if (mutex->curr_locked != -1) {
-        if ((rv = pthread_mutex_destroy(mutex->pthread_interproc))) {
+        if ((rv = pthread_mutex_destroy(mutex->os.pthread_interproc))) {
 #ifdef HAVE_ZOS_PTHREADS
             rv = errno;
 #endif
             return rv;
         }
     }
-    if (munmap((caddr_t)mutex->pthread_interproc, sizeof(pthread_mutex_t))) {
+    if (munmap((caddr_t)mutex->os.pthread_interproc, sizeof(pthread_mutex_t))) {
         return errno;
     }
     return APR_SUCCESS;
@@ -386,12 +382,12 @@ static apr_status_t proc_mutex_proc_pthread_create
         return errno;
     }
 
-    new_mutex->pthread_interproc = (pthread_mutex_t *)mmap(
-                                       (caddr_t) 0, 
-                                       sizeof(pthread_mutex_t), 
-                                       PROT_READ | PROT_WRITE, MAP_SHARED,
-                                       fd, 0); 
-    if (new_mutex->pthread_interproc == (pthread_mutex_t *) (caddr_t) -1) {
+    new_mutex->os.pthread_interproc = (pthread_mutex_t *)mmap(
+                                           (caddr_t) 0, 
+                                           sizeof(pthread_mutex_t), 
+                                           PROT_READ | PROT_WRITE, MAP_SHARED,
+                                           fd, 0); 
+    if (new_mutex->os.pthread_interproc == (pthread_mutex_t *) (caddr_t) -1) {
         close(fd);
         return errno;
     }
@@ -435,7 +431,7 @@ static apr_status_t proc_mutex_proc_pthread_create
     }
 #endif /* HAVE_PTHREAD_MUTEX_ROBUST */
 
-    if ((rv = pthread_mutex_init(new_mutex->pthread_interproc, &mattr))) {
+    if ((rv = pthread_mutex_init(new_mutex->os.pthread_interproc, &mattr))) {
 #ifdef HAVE_ZOS_PTHREADS
         rv = errno;
 #endif
@@ -465,14 +461,14 @@ static apr_status_t proc_mutex_proc_pthread_acquir
 {
     apr_status_t rv;
 
-    if ((rv = pthread_mutex_lock(mutex->pthread_interproc))) {
+    if ((rv = pthread_mutex_lock(mutex->os.pthread_interproc))) {
 #ifdef HAVE_ZOS_PTHREADS
         rv = errno;
 #endif
 #ifdef HAVE_PTHREAD_MUTEX_ROBUST
         /* Okay, our owner died.  Let's try to make it consistent again. */
         if (rv == EOWNERDEAD) {
-            pthread_mutex_consistent_np(mutex->pthread_interproc);
+            pthread_mutex_consistent_np(mutex->os.pthread_interproc);
         }
         else
             return rv;
@@ -488,7 +484,7 @@ static apr_status_t proc_mutex_proc_pthread_tryacq
 {
     apr_status_t rv;
  
-    if ((rv = pthread_mutex_trylock(mutex->pthread_interproc))) {
+    if ((rv = pthread_mutex_trylock(mutex->os.pthread_interproc))) {
 #ifdef HAVE_ZOS_PTHREADS 
         rv = errno;
 #endif
@@ -498,7 +494,7 @@ static apr_status_t proc_mutex_proc_pthread_tryacq
 #ifdef HAVE_PTHREAD_MUTEX_ROBUST
         /* Okay, our owner died.  Let's try to make it consistent again. */
         if (rv == EOWNERDEAD) {
-            pthread_mutex_consistent_np(mutex->pthread_interproc);
+            pthread_mutex_consistent_np(mutex->os.pthread_interproc);
             rv = APR_SUCCESS;
         }
         else
@@ -516,7 +512,7 @@ static apr_status_t proc_mutex_proc_pthread_releas
     apr_status_t rv;
 
     mutex->curr_locked = 0;
-    if ((rv = pthread_mutex_unlock(mutex->pthread_interproc))) {
+    if ((rv = pthread_mutex_unlock(mutex->os.pthread_interproc))) {
 #ifdef HAVE_ZOS_PTHREADS
         rv = errno;
 #endif
@@ -563,7 +559,7 @@ static void proc_mutex_fcntl_setup(void)
 
 static apr_status_t proc_mutex_fcntl_cleanup(void *mutex_)
 {
-    apr_status_t status;
+    apr_status_t status = APR_SUCCESS;
     apr_proc_mutex_t *mutex=mutex_;
 
     if (mutex->curr_locked == 1) {
@@ -572,7 +568,16 @@ static apr_status_t proc_mutex_fcntl_cleanup(void
             return status;
     }
         
-    return apr_file_close(mutex->interproc);
+    if (mutex->interproc) {
+        status = apr_file_close(mutex->interproc);
+    }
+    if (!mutex->closed_by_interproc
+            && mutex->os.crossproc != -1
+            && close(mutex->os.crossproc) == -1
+            && status == APR_SUCCESS) {
+        status = errno;
+    }
+    return status;
 }    
 
 static apr_status_t proc_mutex_fcntl_create(apr_proc_mutex_t *new_mutex,
@@ -598,6 +603,8 @@ static apr_status_t proc_mutex_fcntl_create(apr_pr
         return rv;
     }
 
+    new_mutex->os.crossproc = new_mutex->interproc->filedes;
+    new_mutex->closed_by_interproc = 1;
     new_mutex->curr_locked = 0;
     unlink(new_mutex->fname);
     apr_pool_cleanup_register(new_mutex->pool,
@@ -612,7 +619,7 @@ static apr_status_t proc_mutex_fcntl_acquire(apr_p
     int rc;
 
     do {
-        rc = fcntl(mutex->interproc->filedes, F_SETLKW, &proc_mutex_lock_it);
+        rc = fcntl(mutex->os.crossproc, F_SETLKW, &proc_mutex_lock_it);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         return errno;
@@ -626,7 +633,7 @@ static apr_status_t proc_mutex_fcntl_tryacquire(ap
     int rc;
 
     do {
-        rc = fcntl(mutex->interproc->filedes, F_SETLK, &proc_mutex_lock_it);
+        rc = fcntl(mutex->os.crossproc, F_SETLK, &proc_mutex_lock_it);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
 #if FCNTL_TRYACQUIRE_EACCES
@@ -648,7 +655,7 @@ static apr_status_t proc_mutex_fcntl_release(apr_p
 
     mutex->curr_locked=0;
     do {
-        rc = fcntl(mutex->interproc->filedes, F_SETLKW, &proc_mutex_unlock_it);
+        rc = fcntl(mutex->os.crossproc, F_SETLKW, &proc_mutex_unlock_it);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         return errno;
@@ -665,7 +672,7 @@ static apr_status_t proc_mutex_fcntl_perms_set(apr
     if (mutex->fname) {
         if (!(perms & APR_FPROT_GSETID))
             gid = -1;
-        if (fchown(mutex->interproc->filedes, uid, gid) < 0) {
+        if (fchown(mutex->os.crossproc, uid, gid) < 0) {
             return errno;
         }
     }
@@ -697,7 +704,7 @@ static apr_status_t proc_mutex_flock_release(apr_p
 
 static apr_status_t proc_mutex_flock_cleanup(void *mutex_)
 {
-    apr_status_t status;
+    apr_status_t status = APR_SUCCESS;
     apr_proc_mutex_t *mutex=mutex_;
 
     if (mutex->curr_locked == 1) {
@@ -706,10 +713,18 @@ static apr_status_t proc_mutex_flock_cleanup(void
             return status;
     }
     if (mutex->interproc) { /* if it was opened properly */
-        apr_file_close(mutex->interproc);
+        status = apr_file_close(mutex->interproc);
     }
-    unlink(mutex->fname);
-    return APR_SUCCESS;
+    if (!mutex->closed_by_interproc
+            && mutex->os.crossproc != -1
+            && close(mutex->os.crossproc) == -1
+            && status == APR_SUCCESS) {
+        status = errno;
+    }
+    if (mutex->fname) {
+        unlink(mutex->fname);
+    }
+    return status;
 }    
 
 static apr_status_t proc_mutex_flock_create(apr_proc_mutex_t *new_mutex,
@@ -733,8 +748,11 @@ static apr_status_t proc_mutex_flock_create(apr_pr
  
     if (rv != APR_SUCCESS) {
         proc_mutex_flock_cleanup(new_mutex);
-        return errno;
+        return rv;
     }
+
+    new_mutex->os.crossproc = new_mutex->interproc->filedes;
+    new_mutex->closed_by_interproc = 1;
     new_mutex->curr_locked = 0;
     apr_pool_cleanup_register(new_mutex->pool, (void *)new_mutex,
                               apr_proc_mutex_cleanup,
@@ -747,7 +765,7 @@ static apr_status_t proc_mutex_flock_acquire(apr_p
     int rc;
 
     do {
-        rc = flock(mutex->interproc->filedes, LOCK_EX);
+        rc = flock(mutex->os.crossproc, LOCK_EX);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         return errno;
@@ -761,7 +779,7 @@ static apr_status_t proc_mutex_flock_tryacquire(ap
     int rc;
 
     do {
-        rc = flock(mutex->interproc->filedes, LOCK_EX | LOCK_NB);
+        rc = flock(mutex->os.crossproc, LOCK_EX | LOCK_NB);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         if (errno == EWOULDBLOCK || errno == EAGAIN) {
@@ -779,7 +797,7 @@ static apr_status_t proc_mutex_flock_release(apr_p
 
     mutex->curr_locked = 0;
     do {
-        rc = flock(mutex->interproc->filedes, LOCK_UN);
+        rc = flock(mutex->os.crossproc, LOCK_UN);
     } while (rc < 0 && errno == EINTR);
     if (rc < 0) {
         return errno;
@@ -794,19 +812,25 @@ static apr_status_t proc_mutex_flock_child_init(ap
     apr_proc_mutex_t *new_mutex;
     int rv;
 
-    new_mutex = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
-
-    memcpy(new_mutex, *mutex, sizeof *new_mutex);
-    new_mutex->pool = pool;
     if (!fname) {
         fname = (*mutex)->fname;
+        if (!fname) {
+            return APR_SUCCESS;
+        }
     }
+
+    new_mutex = (apr_proc_mutex_t *)apr_pmemdup(pool, *mutex,
+                                                sizeof(apr_proc_mutex_t));
+    new_mutex->pool = pool;
     new_mutex->fname = apr_pstrdup(pool, fname);
     rv = apr_file_open(&new_mutex->interproc, new_mutex->fname,
                        APR_FOPEN_WRITE, 0, new_mutex->pool);
     if (rv != APR_SUCCESS) {
         return rv;
     }
+    new_mutex->os.crossproc = new_mutex->interproc->filedes;
+    new_mutex->closed_by_interproc = 1;
+
     *mutex = new_mutex;
     return APR_SUCCESS;
 }
@@ -820,7 +844,7 @@ static apr_status_t proc_mutex_flock_perms_set(apr
     if (mutex->fname) {
         if (!(perms & APR_FPROT_GSETID))
             gid = -1;
-        if (fchown(mutex->interproc->filedes, uid, gid) < 0) {
+        if (fchown(mutex->os.crossproc, uid, gid) < 0) {
             return errno;
         }
     }
@@ -857,12 +881,35 @@ void apr_proc_mutex_unix_setup_lock(void)
 #endif
 }
 
-static apr_status_t proc_mutex_choose_method(apr_proc_mutex_t *new_mutex, apr_lockmech_e mech)
+static apr_status_t proc_mutex_choose_method(apr_proc_mutex_t *new_mutex,
+                                             apr_lockmech_e mech,
+                                             apr_os_proc_mutex_t *ospmutex)
 {
+#if APR_HAS_PROC_PTHREAD_SERIALIZE
+    new_mutex->os.pthread_interproc = NULL;
+#endif
+#if APR_HAS_POSIXSEM_SERIALIZE
+    new_mutex->os.psem_interproc = NULL;
+#endif
+#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
+    new_mutex->os.crossproc = -1;
+
+#if APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
+    new_mutex->interproc = NULL;
+    new_mutex->closed_by_interproc = 0;
+#endif
+#endif
+
     switch (mech) {
     case APR_LOCK_FCNTL:
 #if APR_HAS_FCNTL_SERIALIZE
         new_mutex->inter_meth = &mutex_fcntl_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
@@ -870,6 +917,12 @@ void apr_proc_mutex_unix_setup_lock(void)
     case APR_LOCK_FLOCK:
 #if APR_HAS_FLOCK_SERIALIZE
         new_mutex->inter_meth = &mutex_flock_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
@@ -877,6 +930,12 @@ void apr_proc_mutex_unix_setup_lock(void)
     case APR_LOCK_SYSVSEM:
 #if APR_HAS_SYSVSEM_SERIALIZE
         new_mutex->inter_meth = &mutex_sysv_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
@@ -884,6 +943,12 @@ void apr_proc_mutex_unix_setup_lock(void)
     case APR_LOCK_POSIXSEM:
 #if APR_HAS_POSIXSEM_SERIALIZE
         new_mutex->inter_meth = &mutex_posixsem_methods;
+        if (ospmutex) {
+            if (ospmutex->psem_interproc == NULL) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.psem_interproc = ospmutex->psem_interproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
@@ -891,6 +956,12 @@ void apr_proc_mutex_unix_setup_lock(void)
     case APR_LOCK_PROC_PTHREAD:
 #if APR_HAS_PROC_PTHREAD_SERIALIZE
         new_mutex->inter_meth = &mutex_proc_pthread_methods;
+        if (ospmutex) {
+            if (ospmutex->pthread_interproc == NULL) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.pthread_interproc = ospmutex->pthread_interproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
@@ -898,14 +969,44 @@ void apr_proc_mutex_unix_setup_lock(void)
     case APR_LOCK_DEFAULT:
 #if APR_USE_FLOCK_SERIALIZE
         new_mutex->inter_meth = &mutex_flock_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #elif APR_USE_SYSVSEM_SERIALIZE
         new_mutex->inter_meth = &mutex_sysv_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #elif APR_USE_FCNTL_SERIALIZE
         new_mutex->inter_meth = &mutex_fcntl_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #elif APR_USE_PROC_PTHREAD_SERIALIZE
         new_mutex->inter_meth = &mutex_proc_pthread_methods;
+        if (ospmutex) {
+            if (ospmutex->pthread_interproc == NULL) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.pthread_interproc = ospmutex->pthread_interproc;
+        }
 #elif APR_USE_POSIXSEM_SERIALIZE
         new_mutex->inter_meth = &mutex_posixsem_methods;
+        if (ospmutex) {
+            if (ospmutex->psem_interproc == NULL) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.psem_interproc = ospmutex->psem_interproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
@@ -921,7 +1022,8 @@ APR_DECLARE(const char *) apr_proc_mutex_defname(v
     apr_status_t rv;
     apr_proc_mutex_t mutex;
 
-    if ((rv = proc_mutex_choose_method(&mutex, APR_LOCK_DEFAULT)) != APR_SUCCESS) {
+    if ((rv = proc_mutex_choose_method(&mutex, APR_LOCK_DEFAULT,
+                                       NULL)) != APR_SUCCESS) {
         return "unknown";
     }
     mutex.meth = mutex.inter_meth;
@@ -933,7 +1035,8 @@ static apr_status_t proc_mutex_create(apr_proc_mut
 {
     apr_status_t rv;
 
-    if ((rv = proc_mutex_choose_method(new_mutex, mech)) != APR_SUCCESS) {
+    if ((rv = proc_mutex_choose_method(new_mutex, mech,
+                                       NULL)) != APR_SUCCESS) {
         return rv;
     }
 
@@ -1026,24 +1129,16 @@ APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
 APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
                                                 apr_proc_mutex_t *pmutex)
 {
-#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
-    if (pmutex->interproc) {
-        ospmutex->crossproc = pmutex->interproc->filedes;
-    }
-    else {
-        ospmutex->crossproc = -1;
-    }
-#endif
-#if APR_HAS_PROC_PTHREAD_SERIALIZE
-    ospmutex->pthread_interproc = pmutex->pthread_interproc;
-#endif
+    *ospmutex = pmutex->os;
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_put_ex(apr_proc_mutex_t **pmutex,
                                                 apr_os_proc_mutex_t *ospmutex,
+                                                apr_lockmech_e mech,
                                                 apr_pool_t *pool)
 {
+    apr_status_t rv;
     if (pool == NULL) {
         return APR_ENOPOOL;
     }
@@ -1052,12 +1147,20 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(ap
                                                     sizeof(apr_proc_mutex_t));
         (*pmutex)->pool = pool;
     }
-#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
-    apr_os_file_put(&(*pmutex)->interproc, &ospmutex->crossproc, 0, pool);
+    rv = proc_mutex_choose_method(*pmutex, mech, ospmutex);
+#if APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
+    if (rv == APR_SUCCESS && (*pmutex)->os.crossproc != -1) {
+        rv = apr_os_file_put(&(*pmutex)->interproc, &(*pmutex)->os.crossproc,
+                             0, pool);
+    }
 #endif
-#if APR_HAS_PROC_PTHREAD_SERIALIZE
-    (*pmutex)->pthread_interproc = ospmutex->pthread_interproc;
-#endif
-    return APR_SUCCESS;
+    return rv;
 }
 
+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_os_proc_mutex_put_ex(pmutex, ospmutex, APR_LOCK_DEFAULT, pool);
+}
+
Index: locks/beos/proc_mutex.c
===================================================================
--- locks/beos/proc_mutex.c	(revision 1620587)
+++ locks/beos/proc_mutex.c	(working copy)
@@ -154,13 +154,17 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(ap
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_put_ex(apr_proc_mutex_t **pmutex,
                                                 apr_os_proc_mutex_t *ospmutex,
+                                                apr_lockmech_e mech,
                                                 apr_pool_t *pool)
 {
     if (pool == NULL) {
         return APR_ENOPOOL;
     }
+    if (mech != APR_LOCK_DEFAULT) {
+        return APR_ENOTIMPL;
+    }
     if ((*pmutex) == NULL) {
         (*pmutex) = (apr_proc_mutex_t *)apr_pcalloc(pool, sizeof(apr_proc_mutex_t));
         (*pmutex)->pool = pool;
@@ -170,3 +174,10 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(ap
     return APR_SUCCESS;
 }
 
+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_os_proc_mutex_put_ex(pmutex, ospmutex, APR_LOCK_DEFAULT, pool);
+}
+
Index: include/apr_portable.h
===================================================================
--- include/apr_portable.h	(revision 1620587)
+++ include/apr_portable.h	(working copy)
@@ -109,7 +112,7 @@ typedef void*                 apr_os_shm_t;
 typedef int                   apr_os_file_t;
 typedef DIR                   apr_os_dir_t;
 typedef int                   apr_os_sock_t;
-typedef NXMutex_t             apr_os_proc_mutex_t;
+typedef NXMutex_t *           apr_os_proc_mutex_t;
 typedef NXThreadId_t          apr_os_thread_t;
 typedef long                  apr_os_proc_t;
 typedef NXKey_t               apr_os_threadkey_t; 
Index: locks/netware/proc_mutex.c
===================================================================
--- locks/netware/proc_mutex.c	(revision 1620587)
+++ locks/netware/proc_mutex.c	(working copy)
@@ -103,18 +103,40 @@ APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
 
 /* Implement OS-specific accessors defined in apr_portable.h */
 
-apr_status_t apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
-                                   apr_proc_mutex_t *pmutex)
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
+                                                apr_proc_mutex_t *pmutex)
 {
-    if (pmutex)
-        ospmutex = pmutex->mutex->mutex;
-    return APR_ENOLOCK;
+    if (!pmutex->mutex) {
+        return APR_ENOLOCK;
+    }
+    *ospmutex = pmutex->mutex->mutex;
+    return APR_SUCCESS;
 }
 
-apr_status_t apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
-                                   apr_os_proc_mutex_t *ospmutex,
-                                   apr_pool_t *pool)
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_put_ex(apr_proc_mutex_t **pmutex,
+                                                apr_os_proc_mutex_t *ospmutex,
+                                                apr_lockmech_e mech,
+                                                apr_pool_t *pool)
 {
-    return APR_ENOTIMPL;
+    if (pool == NULL) {
+        return APR_ENOPOOL;
+    }
+    if (mech != APR_LOCK_DEFAULT) {
+        return APR_ENOTIMPL;
+    }
+    *pmutex = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
+    (*pmutex)->mutex = (apr_thread_mutex_t*)apr_palloc(pool,
+                                                sizeof(apr_thread_mutex_t));
+    (*pmutex)->mutex->mutex = *ospmutex;
+    (*pmutex)->mutex->pool = pool;
+    (*pmutex)->pool = pool;
+    return APR_SUCCESS;
 }
 
+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_os_proc_mutex_put_ex(pmutex, ospmutex, APR_LOCK_DEFAULT, pool);
+}
+

Reply via email to