Hello community, here is the log from the commit of package libapr1 for openSUSE:Factory checked in at 2016-05-10 09:25:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libapr1 (Old) and /work/SRC/openSUSE:Factory/.libapr1.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libapr1" Changes: -------- --- /work/SRC/openSUSE:Factory/libapr1/libapr1.changes 2015-10-03 20:29:23.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.libapr1.new/libapr1.changes 2016-05-10 09:25:09.000000000 +0200 @@ -1,0 +2,12 @@ +Wed May 4 13:17:03 UTC 2016 - [email protected] + +- 0017-Merge-r1733694-r1733708-from-trunk.patch and + 0018-apr_proc_mutex-unix-backport-r1733775-from-trunk-par.patch + Refcount shared mutexes usage to avoid + destruction while still is use by some processes, this fixes + apache graceful-restart sometimes leaving processes in + "Gracefully finishing" state forever. +- apr-proc-mutex-map-anon.patch use MAP_ANON instead of mmap'ing + /dev/zero. + +------------------------------------------------------------------- New: ---- 0017-Merge-r1733694-r1733708-from-trunk.patch 0018-apr_proc_mutex-unix-backport-r1733775-from-trunk-par.patch apr-proc-mutex-map-anon.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libapr1.spec ++++++ --- /var/tmp/diff_new_pack.nDQpGY/_old 2016-05-10 09:25:10.000000000 +0200 +++ /var/tmp/diff_new_pack.nDQpGY/_new 2016-05-10 09:25:10.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package libapr1 # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -32,6 +32,9 @@ Patch4: apr-1.4.5-linux3.patch Patch5: apr-visibility.patch Patch6: apr-use-getrandom.patch +Patch7: 0017-Merge-r1733694-r1733708-from-trunk.patch +Patch8: 0018-apr_proc_mutex-unix-backport-r1733775-from-trunk-par.patch +Patch9: apr-proc-mutex-map-anon.patch BuildRequires: doxygen BuildRequires: fdupes BuildRequires: libtool @@ -80,6 +83,10 @@ %patch4 %patch5 -p1 %patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 + # Do not put date to doxy content sed -i \ -e '4 iHTML_TIMESTAMP=NO' \ ++++++ 0017-Merge-r1733694-r1733708-from-trunk.patch ++++++ >From f1e4634ad2e1a321a425f7c43b9f60d0d2706686 Mon Sep 17 00:00:00 2001 From: Yann Ylavic <[email protected]> Date: Tue, 12 Apr 2016 13:29:31 +0000 Subject: [PATCH 17/18] Merge r1733694, r1733708 from trunk: apr_proc_mutex-pthread: Refcount shared mutexes usage to avoid destruction while still is use by some process(es). PR 49504. apr_proc_mutex-pthread: follow up to r1733694. Simplify #if/#else/#endif logic, no functional change. Note: this merge additionnaly fixes the munmap()ing size of the pthread_interproc mutex to match the mmap()ed one, which was done in trunk by r1733775 (barely related and backported later), hence the additional change for *this* bugfix to be self contained. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.5.x@1738800 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 +++ locks/unix/proc_mutex.c | 66 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/locks/unix/proc_mutex.c b/locks/unix/proc_mutex.c index 32012a7..13ba2ea 100644 --- a/locks/unix/proc_mutex.c +++ b/locks/unix/proc_mutex.c @@ -19,6 +19,7 @@ #include "apr_arch_proc_mutex.h" #include "apr_arch_file_io.h" /* for apr_mkstemp() */ #include "apr_hash.h" +#include "apr_atomic.h" APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex) { @@ -325,7 +326,24 @@ static const apr_proc_mutex_unix_lock_methods_t mutex_sysv_methods = #if APR_HAS_PROC_PTHREAD_SERIALIZE -static apr_status_t proc_mutex_proc_pthread_cleanup(void *mutex_) +/* The mmap()ed pthread_interproc is the native pthread_mutex_t followed + * by a refcounter to track children using it. We want to avoid calling + * pthread_mutex_destroy() on the shared mutex area while it is in use by + * another process, because this may mark the shared pthread_mutex_t as + * invalid for everyone, including forked children (unlike "sysvsem" for + * example), causing unexpected errors or deadlocks (PR 49504). So the + * last process (parent or child) referencing the mutex will effectively + * destroy it. + */ +typedef struct { + pthread_mutex_t mutex; + apr_uint32_t refcount; +} proc_pthread_mutex_t; + +#define proc_pthread_mutex_refcount(m) \ + (((proc_pthread_mutex_t *)(m)->pthread_interproc)->refcount) + +static apr_status_t proc_pthread_mutex_unref(void *mutex_) { apr_proc_mutex_t *mutex=mutex_; apr_status_t rv; @@ -338,8 +356,7 @@ static apr_status_t proc_mutex_proc_pthread_cleanup(void *mutex_) return rv; } } - /* curr_locked is set to -1 until the mutex has been created */ - if (mutex->curr_locked != -1) { + if (!apr_atomic_dec32(&proc_pthread_mutex_refcount(mutex))) { if ((rv = pthread_mutex_destroy(mutex->pthread_interproc))) { #ifdef HAVE_ZOS_PTHREADS rv = errno; @@ -347,7 +364,22 @@ static apr_status_t proc_mutex_proc_pthread_cleanup(void *mutex_) return rv; } } - if (munmap((caddr_t)mutex->pthread_interproc, sizeof(pthread_mutex_t))) { + return APR_SUCCESS; +} + +static apr_status_t proc_mutex_proc_pthread_cleanup(void *mutex_) +{ + apr_proc_mutex_t *mutex=mutex_; + apr_status_t rv; + + /* curr_locked is set to -1 until the mutex has been created */ + if (mutex->curr_locked != -1) { + if ((rv = proc_pthread_mutex_unref(mutex))) { + return rv; + } + } + if (munmap((caddr_t)mutex->pthread_interproc, + sizeof(proc_pthread_mutex_t))) { return errno; } return APR_SUCCESS; @@ -367,7 +399,7 @@ static apr_status_t proc_mutex_proc_pthread_create(apr_proc_mutex_t *new_mutex, new_mutex->pthread_interproc = (pthread_mutex_t *)mmap( (caddr_t) 0, - sizeof(pthread_mutex_t), + sizeof(proc_pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (new_mutex->pthread_interproc == (pthread_mutex_t *) (caddr_t) -1) { @@ -423,6 +455,7 @@ static apr_status_t proc_mutex_proc_pthread_create(apr_proc_mutex_t *new_mutex, return rv; } + proc_pthread_mutex_refcount(new_mutex) = 1; /* first/parent reference */ new_mutex->curr_locked = 0; /* mutex created now */ if ((rv = pthread_mutexattr_destroy(&mattr))) { @@ -440,6 +473,17 @@ static apr_status_t proc_mutex_proc_pthread_create(apr_proc_mutex_t *new_mutex, return APR_SUCCESS; } +static apr_status_t proc_mutex_proc_pthread_child_init(apr_proc_mutex_t **mutex, + apr_pool_t *pool, + const char *fname) +{ + (*mutex)->curr_locked = 0; + apr_atomic_inc32(&proc_pthread_mutex_refcount(*mutex)); + apr_pool_cleanup_register(pool, *mutex, proc_pthread_mutex_unref, + apr_pool_cleanup_null); + return APR_SUCCESS; +} + static apr_status_t proc_mutex_proc_pthread_acquire(apr_proc_mutex_t *mutex) { apr_status_t rv; @@ -451,13 +495,12 @@ static apr_status_t proc_mutex_proc_pthread_acquire(apr_proc_mutex_t *mutex) #ifdef HAVE_PTHREAD_MUTEX_ROBUST /* Okay, our owner died. Let's try to make it consistent again. */ if (rv == EOWNERDEAD) { + apr_atomic_dec32(&proc_pthread_mutex_refcount(mutex)); pthread_mutex_consistent_np(mutex->pthread_interproc); } else - return rv; -#else - return rv; #endif + return rv; } mutex->curr_locked = 1; return APR_SUCCESS; @@ -478,13 +521,10 @@ static apr_status_t proc_mutex_proc_pthread_tryacquire(apr_proc_mutex_t *mutex) /* Okay, our owner died. Let's try to make it consistent again. */ if (rv == EOWNERDEAD) { pthread_mutex_consistent_np(mutex->pthread_interproc); - rv = APR_SUCCESS; } else - return rv; -#else - return rv; #endif + return rv; } mutex->curr_locked = 1; return rv; @@ -512,7 +552,7 @@ static const apr_proc_mutex_unix_lock_methods_t mutex_proc_pthread_methods = proc_mutex_proc_pthread_tryacquire, proc_mutex_proc_pthread_release, proc_mutex_proc_pthread_cleanup, - proc_mutex_no_child_init, + proc_mutex_proc_pthread_child_init, "pthread" }; -- 2.8.1 ++++++ 0018-apr_proc_mutex-unix-backport-r1733775-from-trunk-par.patch ++++++ >From 129a4883de0795d748a25f110dda6b5c6ab0ea96 Mon Sep 17 00:00:00 2001 From: Yann Ylavic <[email protected]> Date: Tue, 12 Apr 2016 15:55:16 +0000 Subject: [PATCH 18/18] apr_proc_mutex-unix: backport r1733775 from trunk (partially). Includes some fixes to unix proc_mutexes contained in the above commit (including follow up to r1738800), but without non-backportable (API) changes. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.5.x@1738819 13f79535-47bb-0310-9956-ffa450edef68 --- include/arch/unix/apr_arch_proc_mutex.h | 4 +++ locks/unix/proc_mutex.c | 59 ++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/include/arch/unix/apr_arch_proc_mutex.h b/include/arch/unix/apr_arch_proc_mutex.h index ec9796b..4edd0fd 100644 --- a/include/arch/unix/apr_arch_proc_mutex.h +++ b/include/arch/unix/apr_arch_proc_mutex.h @@ -104,6 +104,10 @@ struct apr_proc_mutex_t { #endif #if APR_HAS_PROC_PTHREAD_SERIALIZE pthread_mutex_t *pthread_interproc; + int pthread_refcounting; /* Whether the native mutex is refcounted or + * apr_os_proc_mutex_put()ed, which makes + * refcounting impossible/undesirable. + */ #endif }; diff --git a/locks/unix/proc_mutex.c b/locks/unix/proc_mutex.c index 13ba2ea..dd6c6b0 100644 --- a/locks/unix/proc_mutex.c +++ b/locks/unix/proc_mutex.c @@ -343,6 +343,23 @@ typedef struct { #define proc_pthread_mutex_refcount(m) \ (((proc_pthread_mutex_t *)(m)->pthread_interproc)->refcount) +static APR_INLINE int proc_pthread_mutex_inc(apr_proc_mutex_t *mutex) +{ + if (mutex->pthread_refcounting) { + apr_atomic_inc32(&proc_pthread_mutex_refcount(mutex)); + return 1; + } + return 0; +} + +static APR_INLINE int proc_pthread_mutex_dec(apr_proc_mutex_t *mutex) +{ + if (mutex->pthread_refcounting) { + return apr_atomic_dec32(&proc_pthread_mutex_refcount(mutex)); + } + return 0; +} + static apr_status_t proc_pthread_mutex_unref(void *mutex_) { apr_proc_mutex_t *mutex=mutex_; @@ -356,7 +373,7 @@ static apr_status_t proc_pthread_mutex_unref(void *mutex_) return rv; } } - if (!apr_atomic_dec32(&proc_pthread_mutex_refcount(mutex))) { + if (!proc_pthread_mutex_dec(mutex)) { if ((rv = pthread_mutex_destroy(mutex->pthread_interproc))) { #ifdef HAVE_ZOS_PTHREADS rv = errno; @@ -378,8 +395,7 @@ static apr_status_t proc_mutex_proc_pthread_cleanup(void *mutex_) return rv; } } - if (munmap((caddr_t)mutex->pthread_interproc, - sizeof(proc_pthread_mutex_t))) { + if (munmap(mutex->pthread_interproc, sizeof(proc_pthread_mutex_t))) { return errno; } return APR_SUCCESS; @@ -397,17 +413,17 @@ static apr_status_t proc_mutex_proc_pthread_create(apr_proc_mutex_t *new_mutex, return errno; } - new_mutex->pthread_interproc = (pthread_mutex_t *)mmap( - (caddr_t) 0, - sizeof(proc_pthread_mutex_t), - PROT_READ | PROT_WRITE, MAP_SHARED, - fd, 0); - if (new_mutex->pthread_interproc == (pthread_mutex_t *) (caddr_t) -1) { + new_mutex->pthread_interproc = mmap(NULL, sizeof(proc_pthread_mutex_t), + PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0); + if (new_mutex->pthread_interproc == MAP_FAILED) { + rv = errno; close(fd); - return errno; + return rv; } close(fd); + new_mutex->pthread_refcounting = 1; new_mutex->curr_locked = -1; /* until the mutex has been created */ if ((rv = pthread_mutexattr_init(&mattr))) { @@ -478,9 +494,10 @@ static apr_status_t proc_mutex_proc_pthread_child_init(apr_proc_mutex_t **mutex, const char *fname) { (*mutex)->curr_locked = 0; - apr_atomic_inc32(&proc_pthread_mutex_refcount(*mutex)); - apr_pool_cleanup_register(pool, *mutex, proc_pthread_mutex_unref, - apr_pool_cleanup_null); + if (proc_pthread_mutex_inc(*mutex)) { + apr_pool_cleanup_register(pool, *mutex, proc_pthread_mutex_unref, + apr_pool_cleanup_null); + } return APR_SUCCESS; } @@ -495,7 +512,7 @@ static apr_status_t proc_mutex_proc_pthread_acquire(apr_proc_mutex_t *mutex) #ifdef HAVE_PTHREAD_MUTEX_ROBUST /* Okay, our owner died. Let's try to make it consistent again. */ if (rv == EOWNERDEAD) { - apr_atomic_dec32(&proc_pthread_mutex_refcount(mutex)); + proc_pthread_mutex_dec(mutex); pthread_mutex_consistent_np(mutex->pthread_interproc); } else @@ -520,6 +537,7 @@ static apr_status_t proc_mutex_proc_pthread_tryacquire(apr_proc_mutex_t *mutex) #ifdef HAVE_PTHREAD_MUTEX_ROBUST /* Okay, our owner died. Let's try to make it consistent again. */ if (rv == EOWNERDEAD) { + proc_pthread_mutex_dec(mutex); pthread_mutex_consistent_np(mutex->pthread_interproc); } else @@ -527,7 +545,7 @@ static apr_status_t proc_mutex_proc_pthread_tryacquire(apr_proc_mutex_t *mutex) return rv; } mutex->curr_locked = 1; - return rv; + return APR_SUCCESS; } static apr_status_t proc_mutex_proc_pthread_release(apr_proc_mutex_t *mutex) @@ -734,8 +752,9 @@ static apr_status_t proc_mutex_flock_create(apr_proc_mutex_t *new_mutex, if (rv != APR_SUCCESS) { proc_mutex_flock_cleanup(new_mutex); - return errno; + return rv; } + new_mutex->curr_locked = 0; apr_pool_cleanup_register(new_mutex->pool, (void *)new_mutex, apr_proc_mutex_cleanup, @@ -795,13 +814,13 @@ static apr_status_t proc_mutex_flock_child_init(apr_proc_mutex_t **mutex, 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; } + + 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); -- 2.8.1 ++++++ apr-proc-mutex-map-anon.patch ++++++ Index: apr-1.5.2/locks/unix/proc_mutex.c =================================================================== --- apr-1.5.2.orig/locks/unix/proc_mutex.c +++ apr-1.5.2/locks/unix/proc_mutex.c @@ -405,23 +405,15 @@ static apr_status_t proc_mutex_proc_pthr const char *fname) { apr_status_t rv; - int fd; pthread_mutexattr_t mattr; - fd = open("/dev/zero", O_RDWR); - if (fd < 0) { - return errno; - } - new_mutex->pthread_interproc = mmap(NULL, sizeof(proc_pthread_mutex_t), - PROT_READ | PROT_WRITE, MAP_SHARED, - fd, 0); + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, + -1, 0); if (new_mutex->pthread_interproc == MAP_FAILED) { rv = errno; - close(fd); return rv; } - close(fd); new_mutex->pthread_refcounting = 1; new_mutex->curr_locked = -1; /* until the mutex has been created */
