[prev in list] [next in list] [prev in thread] [next in thread] 

List:       apr-dev
Subject:    Re: apr_os_proc_mutex_get/set[_ex] for supported mechanisms
From:       Yann Ylavic <ylavic.dev () gmail ! com>
Date:       2014-10-01 14:24:42
Message-ID: CAKQ1sVPp74h8EROkqDXvqo9JaMmq0op-Zskj6Xv=TZGp4z287A () mail ! gmail ! com
[Download RAW message or body]

Here are v2 of the previous patch(es) with the following addons :

1. Really address the showstopper from
http://svn.apache.org/viewvc?view=revision&revision=1587066

The previous patch only addressed the impossibility to specify the
mechanism when set()ting an APR proc mutex from a OS proc mutex
(disambiguation on unixes with multiple mechanisms using the fd
available).
This time the patch addresses the get() part of the issue, by introducing :

APR_DECLARE(apr_status_t) apr_os_proc_mutex_get_ex(apr_os_proc_mutex_t
*ospmutex,
                                                   apr_proc_mutex_t *pmutex,
                                                   apr_lockmech_e *mech);

so that the caller can also get the mechanism used by the mutex.

Again, like with apr_os_proc_mutex_set_ex(), I choose to not add the
apr_lockmech_e to the apr_os_proc_mutex_t but instead use a new _ex()
function. This allows to be compatible with the existing codes which
would not have been aware of the new apr_os_proc_mutex_t field, with
an uninitialized value for the mech that we could not have relied on.

The new function is implemented on all platforms, and APR_LOCK_DEFAULT
is used when only one mech is available.

For unixes, the mech has been added to the
apr_proc_mutex_unix_lock_methods_t struct (where the mech's name is
already defined), so that it can be accessed immediatly with
mutex->meth->mech (like mutex->meth->name).


2. Since apr_[global/proc]_mutex_name() are already available to get
the name of the mech, I also added apr_[global/proc]_mutex_mech().

Hence the caller can get the enum easily from the mutex (eg. without
strcmp(apr_proc_mutex_name(mutex), "sysvsem") for every possible name
like in httpd/os/unix/unixd.c).


3. Configure PROC_PTHREAD mutexes to be "global" (ie. they are also
thread locking) in configure.in

This matters for apr_global_mutex_t where APR_PROC_MUTEX_IS_GLOBAL is
checked to determine whether an associated thread mutex is required to
be thread-safe. When the (default) proc-mutex is "global", all the
apr_global_mutex_* functions and types are #defined to the
corresponding proc-mutex ones, otherwise apr_global_mutex_t is a
struct containing both a proc and thread mutex, and the 2 locks are
successively acquired/released upon apr_global_mutex_lock/unlock().

This is not needed for proc-pthread mutexes, but since this is now the
first (default) global proc-mutex mechanism on unixes, the case was
not handled in include/arch/unix/apr_arch_global_mutex.h nor in
locks/unix/global_mutex.c, and I had to use some #if
!APR_PROC_MUTEX_IS_GLOBAL there to disable the global-mutex specific
code.

I also added a missing #define apr_global_mutex_perms_set
apr_proc_mutex_perms_set when the proc-mutex is global.


All the rest remain as decribed below (previous message).

On Tue, Sep 30, 2014 at 10:35 PM, Yann Ylavic <ylavic.dev@gmail.com> wrote:
>
> 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).

["proc_mutex-v2.patch" (text/x-diff)]

Index: configure.in
===================================================================
--- configure.in	(revision 1628634)
+++ configure.in	(working copy)
@@ -665,7 +665,6 @@ if test $force_generic_atomics = yes; then
              [Define if use of generic atomics is requested])
 fi
 
-AC_SUBST(proc_mutex_is_global)
 AC_SUBST(eolstr)
 AC_SUBST(INSTALL_SUBDIRS)
 
@@ -2213,6 +2212,7 @@ case $ac_decision in
         ;;
     USE_PROC_PTHREAD_SERIALIZE )
         procpthreadser="1"
+        proc_mutex_is_global=1
         ;;
     USE_BEOSSEM )
         beossem="1"
@@ -2298,6 +2298,8 @@ AC_SUBST(fcntlser)
 AC_SUBST(procpthreadser)
 AC_SUBST(pthreadser)
 
+AC_SUBST(proc_mutex_is_global)
+
 AC_MSG_CHECKING(if all interprocess locks affect threads)
 if test "x$apr_process_lock_is_global" = "xyes"; then
     proclockglobal="1"
Index: include/apr_portable.h
===================================================================
--- include/apr_portable.h	(revision 1628634)
+++ 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 */
@@ -241,7 +248,7 @@ APR_DECLARE(apr_status_t) apr_os_sock_get(apr_os_s
                                           apr_socket_t *sock);
 
 /**
- * Convert the proc mutex from os specific type to apr type
+ * Convert the proc mutex from apr type to os specific type
  * @param ospmutex The os specific proc mutex we are converting to.
  * @param pmutex The apr proc mutex to convert.
  */
@@ -249,6 +256,19 @@ APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(ap
                                                 apr_proc_mutex_t *pmutex);
 
 /**
+ * Convert the proc mutex from apr type to os specific type, also
+ * providing the mechanism used by the apr mutex.
+ * @param ospmutex The os specific proc mutex we are converting to.
+ * @param pmutex The apr proc mutex to convert.
+ * @param mech The mechanism used by the apr proc mutex (if not NULL).
+ * @remark Allows for disambiguation for platforms with multiple mechanisms
+ *         available.
+ */
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_get_ex(apr_os_proc_mutex_t *ospmutex, 
+                                                   apr_proc_mutex_t *pmutex,
+                                                   apr_lockmech_e *mech);
+
+/**
  * Get the exploded time in the platforms native format.
  * @param ostime the native time format
  * @param aprtime the time to convert
@@ -416,6 +436,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, using 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/apr_global_mutex.h
===================================================================
--- include/apr_global_mutex.h	(revision 1628634)
+++ include/apr_global_mutex.h	(working copy)
@@ -128,11 +128,17 @@ APR_DECLARE(apr_status_t) apr_global_mutex_destroy
 APR_DECLARE(const char *) apr_global_mutex_lockfile(apr_global_mutex_t *mutex);
 
 /**
- * Display the name of the mutex, as it relates to the actual method used
- * for the underlying apr_proc_mutex_t, if any.  NULL is returned if
- * there is no underlying apr_proc_mutex_t.
- * @param mutex the name of the mutex
+ * Get the mechanism of the mutex, as it relates to the actual method
+ * used for the underlying apr_proc_mutex_t.
+ * @param mutex the mutex to get the mechanism from.
  */
+APR_DECLARE(apr_lockmech_e) apr_global_mutex_mech(apr_global_mutex_t *mutex);
+
+/**
+ * Get the mechanism's name of the mutex, as it relates to the actual method
+ * used for the underlying apr_proc_mutex_t.
+ * @param mutex the mutex to get the mechanism's name from.
+ */
 APR_DECLARE(const char *) apr_global_mutex_name(apr_global_mutex_t *mutex);
 
 /**
@@ -161,7 +167,9 @@ APR_POOL_DECLARE_ACCESSOR(global_mutex);
 #define apr_global_mutex_unlock     apr_proc_mutex_unlock
 #define apr_global_mutex_destroy    apr_proc_mutex_destroy
 #define apr_global_mutex_lockfile   apr_proc_mutex_lockfile
+#define apr_global_mutex_mech       apr_proc_mutex_mech
 #define apr_global_mutex_name       apr_proc_mutex_name
+#define apr_global_mutex_perms_set  apr_proc_mutex_perms_set
 #define apr_global_mutex_pool_get   apr_proc_mutex_pool_get
 
 #endif
Index: include/apr_proc_mutex.h
===================================================================
--- include/apr_proc_mutex.h	(revision 1628634)
+++ include/apr_proc_mutex.h	(working copy)
@@ -141,10 +141,17 @@ APR_DECLARE(apr_status_t) apr_proc_mutex_cleanup(v
 APR_DECLARE(const char *) apr_proc_mutex_lockfile(apr_proc_mutex_t *mutex);
 
 /**
- * Display the name of the mutex, as it relates to the actual method used.
- * This matches the valid options for Apache's AcceptMutex directive
- * @param mutex the name of the mutex
+ * Get the mechanism of the mutex, as it relates to the actual method
+ * used for the underlying apr_proc_mutex_t.
+ * @param mutex the mutex to get the mechanism from.
  */
+APR_DECLARE(apr_lockmech_e) apr_proc_mutex_mech(apr_proc_mutex_t *mutex);
+
+/**
+ * Get the mechanism's name of the mutex, as it relates to the actual method
+ * used for the underlying apr_proc_mutex_t.
+ * @param mutex the mutex to get the mechanism's name from.
+ */
 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex);
 
 /**
Index: include/arch/unix/apr_arch_global_mutex.h
===================================================================
--- include/arch/unix/apr_arch_global_mutex.h	(revision 1628634)
+++ include/arch/unix/apr_arch_global_mutex.h	(working copy)
@@ -18,11 +18,14 @@
 #define GLOBAL_MUTEX_H
 
 #include "apr.h"
+#include "apr_global_mutex.h"
+#include "apr_arch_proc_mutex.h"
+
+#if !APR_PROC_MUTEX_IS_GLOBAL
+
 #include "apr_private.h"
 #include "apr_general.h"
 #include "apr_lib.h"
-#include "apr_global_mutex.h"
-#include "apr_arch_proc_mutex.h"
 #include "apr_arch_thread_mutex.h"
 
 struct apr_global_mutex_t {
@@ -33,5 +36,7 @@ struct apr_global_mutex_t {
 #endif /* APR_HAS_THREADS */
 };
 
+#endif /* !APR_PROC_MUTEX_IS_GLOBAL */
+
 #endif  /* GLOBAL_MUTEX_H */
 
Index: include/arch/unix/apr_arch_proc_mutex.h
===================================================================
--- include/arch/unix/apr_arch_proc_mutex.h	(revision 1628634)
+++ 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 {
@@ -76,6 +73,7 @@ struct apr_proc_mutex_unix_lock_methods_t {
     apr_status_t (*cleanup)(void *);
     apr_status_t (*child_init)(apr_proc_mutex_t **, apr_pool_t *, const char *);
     apr_status_t (*perms_set)(apr_proc_mutex_t *, apr_fileperms_t, apr_uid_t, \
apr_gid_t); +    apr_lockmech_e mech;
     const char *name;
 };
 typedef struct apr_proc_mutex_unix_lock_methods_t \
apr_proc_mutex_unix_lock_methods_t; @@ -94,18 +92,13 @@ union semun {
 struct apr_proc_mutex_t {
     apr_pool_t *pool;
     const apr_proc_mutex_unix_lock_methods_t *meth;
-    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/unix/global_mutex.c
===================================================================
--- locks/unix/global_mutex.c	(revision 1628634)
+++ locks/unix/global_mutex.c	(working copy)
@@ -15,6 +15,9 @@
  */
 
 #include "apr.h"
+
+#if !APR_PROC_MUTEX_IS_GLOBAL
+
 #include "apr_strings.h"
 #include "apr_arch_global_mutex.h"
 #include "apr_proc_mutex.h"
@@ -59,7 +62,7 @@ APR_DECLARE(apr_status_t) apr_global_mutex_create(
     }
 
 #if APR_HAS_THREADS
-    if (m->proc_mutex->inter_meth->flags & APR_PROCESS_LOCK_MECH_IS_GLOBAL) {
+    if (m->proc_mutex->meth->flags & APR_PROCESS_LOCK_MECH_IS_GLOBAL) {
         m->thread_mutex = NULL; /* We don't need a thread lock. */
     }
     else {
@@ -180,6 +183,11 @@ APR_DECLARE(const char *) apr_global_mutex_lockfil
     return apr_proc_mutex_lockfile(mutex->proc_mutex);
 }
 
+APR_DECLARE(apr_lockmech_e) apr_global_mutex_mech(apr_proc_mutex_t *mutex)
+{
+    return apr_proc_mutex_mech(mutex->proc_mutex);
+}
+
 APR_DECLARE(const char *) apr_global_mutex_name(apr_global_mutex_t *mutex)
 {
     return apr_proc_mutex_name(mutex->proc_mutex);
@@ -195,3 +203,6 @@ APR_PERMS_SET_IMPLEMENT(global_mutex)
 }
 
 APR_POOL_IMPLEMENT_ACCESSOR(global_mutex)
+
+#endif /* !APR_PROC_MUTEX_IS_GLOBAL */
+
Index: locks/unix/proc_mutex.c
===================================================================
--- locks/unix/proc_mutex.c	(revision 1628634)
+++ locks/unix/proc_mutex.c	(working copy)
@@ -56,7 +56,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 +71,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 +133,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 +146,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 +160,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 +175,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;
@@ -199,6 +197,7 @@ static const apr_proc_mutex_unix_lock_methods_t mu
     proc_mutex_posix_cleanup,
     proc_mutex_no_child_init,
     proc_mutex_no_perms_set,
+    APR_LOCK_POSIXSEM,
     "posixsem"
 };
 
@@ -228,9 +227,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 +240,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 +265,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 +279,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 +297,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 +317,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;
@@ -339,6 +337,7 @@ static const apr_proc_mutex_unix_lock_methods_t mu
     proc_mutex_sysv_cleanup,
     proc_mutex_no_child_init,
     proc_mutex_sysv_perms_set,
+    APR_LOCK_SYSVSEM,
     "sysvsem"
 };
 
@@ -352,7 +351,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 +360,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 +385,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 +434,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 +464,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 +487,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 +497,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 +515,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
@@ -535,6 +534,7 @@ static const apr_proc_mutex_unix_lock_methods_t mu
     proc_mutex_proc_pthread_cleanup,
     proc_mutex_no_child_init,
     proc_mutex_no_perms_set,
+    APR_LOCK_PROC_PTHREAD,
     "pthread"
 };
 
@@ -563,7 +563,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 +572,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 +607,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 +623,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 +637,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 +659,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 +676,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;
         }
     }
@@ -686,6 +697,7 @@ static const apr_proc_mutex_unix_lock_methods_t mu
     proc_mutex_fcntl_cleanup,
     proc_mutex_no_child_init,
     proc_mutex_fcntl_perms_set,
+    APR_LOCK_FCNTL,
     "fcntl"
 };
 
@@ -697,7 +709,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 +718,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 +753,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 +770,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 +784,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 +802,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 +817,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 +849,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;
         }
     }
@@ -841,6 +870,7 @@ static const apr_proc_mutex_unix_lock_methods_t mu
     proc_mutex_flock_cleanup,
     proc_mutex_flock_child_init,
     proc_mutex_flock_perms_set,
+    APR_LOCK_FLOCK,
     "flock"
 };
 
@@ -857,55 +887,132 @@ 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;
+        new_mutex->meth = &mutex_fcntl_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
         break;
     case APR_LOCK_FLOCK:
 #if APR_HAS_FLOCK_SERIALIZE
-        new_mutex->inter_meth = &mutex_flock_methods;
+        new_mutex->meth = &mutex_flock_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
         break;
     case APR_LOCK_SYSVSEM:
 #if APR_HAS_SYSVSEM_SERIALIZE
-        new_mutex->inter_meth = &mutex_sysv_methods;
+        new_mutex->meth = &mutex_sysv_methods;
+        if (ospmutex) {
+            if (ospmutex->crossproc == -1) {
+                return APR_EINVAL;
+            }
+            new_mutex->os.crossproc = ospmutex->crossproc;
+        }
 #else
         return APR_ENOTIMPL;
 #endif
         break;
     case APR_LOCK_POSIXSEM:
 #if APR_HAS_POSIXSEM_SERIALIZE
-        new_mutex->inter_meth = &mutex_posixsem_methods;
+        new_mutex->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
         break;
     case APR_LOCK_PROC_PTHREAD:
 #if APR_HAS_PROC_PTHREAD_SERIALIZE
-        new_mutex->inter_meth = &mutex_proc_pthread_methods;
+        new_mutex->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
         break;
     case APR_LOCK_DEFAULT:
 #if APR_USE_FLOCK_SERIALIZE
-        new_mutex->inter_meth = &mutex_flock_methods;
+        new_mutex->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;
+        new_mutex->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;
+        new_mutex->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;
+        new_mutex->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;
+        new_mutex->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,10 +1028,10 @@ 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;
 
     return apr_proc_mutex_name(&mutex);
 }
@@ -933,12 +1040,11 @@ 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;
     }
 
-    new_mutex->meth = new_mutex->inter_meth;
-
     if ((rv = new_mutex->meth->create(new_mutex, fname)) != APR_SUCCESS) {
         return rv;
     }
@@ -991,6 +1097,11 @@ APR_DECLARE(apr_status_t) apr_proc_mutex_cleanup(v
     return ((apr_proc_mutex_t *)mutex)->meth->cleanup(mutex);
 }
 
+APR_DECLARE(apr_lockmech_e) apr_proc_mutex_mech(apr_proc_mutex_t *mutex)
+{
+    return mutex->meth->mech;
+}
+
 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
 {
     return mutex->meth->name;
@@ -1023,27 +1134,29 @@ 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)
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_get_ex(apr_os_proc_mutex_t *ospmutex, 
+                                                   apr_proc_mutex_t *pmutex,
+                                                   apr_lockmech_e *mech)
 {
-#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;
+    *ospmutex = pmutex->os;
+    if (mech) {
+        *mech = pmutex->meth->mech;
     }
-    else {
-        ospmutex->crossproc = -1;
-    }
-#endif
-#if APR_HAS_PROC_PTHREAD_SERIALIZE
-    ospmutex->pthread_interproc = pmutex->pthread_interproc;
-#endif
     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_get(apr_os_proc_mutex_t *ospmutex,
+                                                apr_proc_mutex_t *pmutex)
+{
+    return apr_os_proc_mutex_get_ex(ospmutex, pmutex, NULL);
+}
+
+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 +1165,20 @@ APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
                                                     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/win32/proc_mutex.c
===================================================================
--- locks/win32/proc_mutex.c	(revision 1628634)
+++ locks/win32/proc_mutex.c	(working copy)
@@ -189,6 +189,11 @@ APR_DECLARE(const char *) apr_proc_mutex_lockfile(
     return mutex->fname;
 }
 
+APR_DECLARE(apr_lockmech_e) apr_proc_mutex_mech(apr_proc_mutex_t *mutex)
+{
+    return APR_LOCK_DEFAULT;
+}
+
 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
 {
     return apr_proc_mutex_defname();
@@ -205,20 +210,34 @@ 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 *mutex)
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_get_ex(apr_os_proc_mutex_t *ospmutex, 
+                                                   apr_proc_mutex_t *pmutex,
+                                                   apr_lockmech_e *mech)
 {
     *ospmutex = mutex->handle;
+    if (mech) {
+        *mech = APR_LOCK_DEFAULT;
+    }
     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_get(apr_os_proc_mutex_t *ospmutex,
+                                                apr_proc_mutex_t *pmutex)
+{
+    return apr_os_proc_mutex_get_ex(ospmutex, pmutex, NULL);
+}
+
+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 +247,10 @@ APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
     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 1628634)
+++ locks/os2/proc_mutex.c	(working copy)
@@ -60,6 +60,11 @@ APR_DECLARE(const char *) apr_proc_mutex_lockfile(
     return NULL;
 }
 
+APR_DECLARE(apr_lockmech_e) apr_proc_mutex_mech(apr_proc_mutex_t *mutex)
+{
+    return APR_LOCK_DEFAULT;
+}
+
 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
 {
     return "os2sem";
@@ -207,20 +212,35 @@ 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_ex(apr_os_proc_mutex_t *ospmutex, 
+                                                   apr_proc_mutex_t *pmutex,
+                                                   apr_lockmech_e *mech)
+{
+    *ospmutex = pmutex->hMutex;
+    if (mech) {
+        *mech = APR_LOCK_DEFAULT;
+    }
+    return APR_SUCCESS;
+}
+
 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;
+    return apr_os_proc_mutex_get_ex(ospmutex, pmutex, NULL);
 }
 
-
-
-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 +252,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/beos/proc_mutex.c
===================================================================
--- locks/beos/proc_mutex.c	(revision 1628634)
+++ locks/beos/proc_mutex.c	(working copy)
@@ -130,6 +130,11 @@ APR_DECLARE(const char *) apr_proc_mutex_lockfile(
     return NULL;
 }
 
+APR_DECLARE(apr_lockmech_e) apr_proc_mutex_mech(apr_proc_mutex_t *mutex)
+{
+    return APR_LOCK_DEFAULT;
+}
+
 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
 {
     return "beossem";
@@ -146,21 +151,35 @@ 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)
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_get_ex(apr_os_proc_mutex_t *ospmutex, 
+                                                   apr_proc_mutex_t *pmutex,
+                                                   apr_lockmech_e *mech)
 {
     ospmutex->sem = pmutex->Lock;
     ospmutex->ben = pmutex->LockCount;
+    if (mech) {
+        *mech = APR_LOCK_DEFAULT;
+    }
     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_get(apr_os_proc_mutex_t *ospmutex,
+                                                apr_proc_mutex_t *pmutex)
+{
+    return apr_os_proc_mutex_get_ex(ospmutex, pmutex, NULL);
+}
+
+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 +189,10 @@ APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
     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);
+}
+


["proc_mutex-netware-v2.patch" (text/x-diff)]

Index: include/apr_portable.h
===================================================================
--- include/apr_portable.h	(revision 1628634)
+++ include/apr_portable.h	(working copy)
@@ -109,7 +109,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 1628634)
+++ locks/netware/proc_mutex.c	(working copy)
@@ -87,6 +87,11 @@ APR_DECLARE(const char *) apr_proc_mutex_lockfile(
     return NULL;
 }
 
+APR_DECLARE(apr_lockmech_e) apr_proc_mutex_mech(apr_proc_mutex_t *mutex)
+{
+    return APR_LOCK_DEFAULT;
+}
+
 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
 {
     return "netwarethread";
@@ -103,18 +108,51 @@ 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_ex(apr_os_proc_mutex_t *ospmutex, 
+                                                   apr_proc_mutex_t *pmutex,
+                                                   apr_lockmech_e *mech)
 {
-    if (pmutex)
-        ospmutex = pmutex->mutex->mutex;
-    return APR_ENOLOCK;
+    if (!pmutex->mutex) {
+        return APR_ENOLOCK;
+    }
+    *ospmutex = pmutex->mutex->mutex;
+    if (mech) {
+        *mech = APR_LOCK_DEFAULT;
+    }
+    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_get(apr_os_proc_mutex_t *ospmutex,
+                                                apr_proc_mutex_t *pmutex)
 {
-    return APR_ENOTIMPL;
+    return apr_os_proc_mutex_get_ex(ospmutex, pmutex, NULL);
 }
 
+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_pcalloc(pool, sizeof(apr_proc_mutex_t));
+        (*pmutex)->pool = pool;
+    }
+    (*pmutex)->mutex = apr_pcalloc(pool, sizeof(apr_thread_mutex_t));
+    (*pmutex)->mutex->mutex = *ospmutex;
+    (*pmutex)->mutex->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);
+}
+


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic