You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by yl...@apache.org on 2016/04/12 15:29:31 UTC

svn commit: r1738800 - in /apr/apr/branches/1.5.x: ./ CHANGES locks/unix/proc_mutex.c

Author: ylavic
Date: Tue Apr 12 13:29:31 2016
New Revision: 1738800

URL: http://svn.apache.org/viewvc?rev=1738800&view=rev
Log:
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.


Modified:
    apr/apr/branches/1.5.x/   (props changed)
    apr/apr/branches/1.5.x/CHANGES
    apr/apr/branches/1.5.x/locks/unix/proc_mutex.c

Propchange: apr/apr/branches/1.5.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr 12 13:29:31 2016
@@ -1,4 +1,4 @@
 /apr/apr/branches/1.4.x:1003369,1101301
 /apr/apr/branches/1.6.x:1593600,1593612,1648831,1666812,1696141,1696768,1722549,1722558
-/apr/apr/trunk:733052,739635,746310,747990,748080,748361,748371,748565,748888,748902,748988,749810,760443,767895,775683,782838,783398,783958,784633,784773,788588,789050,793192-793193,794118,794485,795267,799497,800627,809745,809854,810472,811455,813063,821306,829490,831641,832904,835607,888669,892028,892159,892909,896382,896653,908427,910419,910597,917819,917837-917838,925965,929796,931973,951771,960665,960671,979891,983618,989450,990435,1003338,1044440,1044447,1055657,1072165,1078845,1081462,1081495,1083038,1083242,1084662,1086695,1088023,1089031,1089129,1089438,1099348,1103310,1183683,1183685-1183686,1183688,1183693,1183698,1213382,1235047,1236970,1237078,1237507,1240472,1340286,1340288,1340470,1341193,1341196,1343233,1343243,1367050,1368819,1370494,1372018,1372022,1372093,1372849,1376957,1384764,1389077,1400200,1402868,1405985,1406690,1420106,1420109,1425356,1428809,1438940,1438958,1442903,1449568,1456418,1459994,1460179,1460241,1460399,1460405,1462738,1462813,1470186,1470348,147
 5509,1478905,1480067,1481262,1481265,1484271,1487796,1489517,1496407,1502804,1510354,1516261,1523384,1523479,1523484,1523505,1523521,1523604,1523613,1523615,1523844-1523845,1523853,1524014,1524031,1528797,1528809,1529488,1529495,1529515,1529521,1529668,1530786,1530800,1530988,1531554,1531768,1531884,1532022,1533104,1533111,1533979,1535027,1535157,1536744,1538171,1539374,1539389,1539455,1539603,1541054,1541061,1541486,1541655,1541666,1541744,1542601,1542779,1543033,1543056,1548575,1550907,1551650,1551659,1558905,1559382,1559873,1559975,1561260,1561265,1561321,1561347,1561356,1561361,1561394,1561555,1571894,1575509,1578420,1587063,1587545,1589982,1593611,1604596,1604598,1610854,1611004,1611023,1611107,1611110,1611120,1611125,1611184,1611193,1611466,1626564,1634615,1642159,1648830,1664406,1664447,1664451,1664471,1664769,1664775,1664904,1664911,1664958,1666341,1666411,1666458,1666611,1667914-1667916,1671329,1671356,1671514,1672354,1672366,1672495,1672575,1675644,1675656,1675668,1676013,
 1685929,1696140,1696767,1722547,1722557,1736552
+/apr/apr/trunk:733052,739635,746310,747990,748080,748361,748371,748565,748888,748902,748988,749810,760443,767895,775683,782838,783398,783958,784633,784773,788588,789050,793192-793193,794118,794485,795267,799497,800627,809745,809854,810472,811455,813063,821306,829490,831641,832904,835607,888669,892028,892159,892909,896382,896653,908427,910419,910597,917819,917837-917838,925965,929796,931973,951771,960665,960671,979891,983618,989450,990435,1003338,1044440,1044447,1055657,1072165,1078845,1081462,1081495,1083038,1083242,1084662,1086695,1088023,1089031,1089129,1089438,1099348,1103310,1183683,1183685-1183686,1183688,1183693,1183698,1213382,1235047,1236970,1237078,1237507,1240472,1340286,1340288,1340470,1341193,1341196,1343233,1343243,1367050,1368819,1370494,1372018,1372022,1372093,1372849,1376957,1384764,1389077,1400200,1402868,1405985,1406690,1420106,1420109,1425356,1428809,1438940,1438958,1442903,1449568,1456418,1459994,1460179,1460241,1460399,1460405,1462738,1462813,1470186,1470348,147
 5509,1478905,1480067,1481262,1481265,1484271,1487796,1489517,1496407,1502804,1510354,1516261,1523384,1523479,1523484,1523505,1523521,1523604,1523613,1523615,1523844-1523845,1523853,1524014,1524031,1528797,1528809,1529488,1529495,1529515,1529521,1529668,1530786,1530800,1530988,1531554,1531768,1531884,1532022,1533104,1533111,1533979,1535027,1535157,1536744,1538171,1539374,1539389,1539455,1539603,1541054,1541061,1541486,1541655,1541666,1541744,1542601,1542779,1543033,1543056,1548575,1550907,1551650,1551659,1558905,1559382,1559873,1559975,1561260,1561265,1561321,1561347,1561356,1561361,1561394,1561555,1571894,1575509,1578420,1587063,1587545,1589982,1593611,1604596,1604598,1610854,1611004,1611023,1611107,1611110,1611120,1611125,1611184,1611193,1611466,1626564,1634615,1642159,1648830,1664406,1664447,1664451,1664471,1664769,1664775,1664904,1664911,1664958,1666341,1666411,1666458,1666611,1667914-1667916,1671329,1671356,1671514,1672354,1672366,1672495,1672575,1675644,1675656,1675668,1676013,
 1685929,1696140,1696767,1722547,1722557,1733694,1733708,1736552
 /apr/apr/trunk/test/testnames.c:1460405

Modified: apr/apr/branches/1.5.x/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.5.x/CHANGES?rev=1738800&r1=1738799&r2=1738800&view=diff
==============================================================================
--- apr/apr/branches/1.5.x/CHANGES [utf-8] (original)
+++ apr/apr/branches/1.5.x/CHANGES [utf-8] Tue Apr 12 13:29:31 2016
@@ -1,6 +1,10 @@
                                                      -*- coding: utf-8 -*-
 Changes for APR 1.5.3
 
+  *) apr_proc_mutex-pthread: Refcount shared mutexes usage to avoid
+     destruction while still is use by some process(es).  PR 49504.
+     [Yann Ylavic]
+
   *) apr_mcast_interface/apr_mcast_join: Fix comparison of IPv6 addresses.
      [ Andre Naujoks <nautsch2 gmail com> ]
 

Modified: apr/apr/branches/1.5.x/locks/unix/proc_mutex.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.5.x/locks/unix/proc_mutex.c?rev=1738800&r1=1738799&r2=1738800&view=diff
==============================================================================
--- apr/apr/branches/1.5.x/locks/unix/proc_mutex.c (original)
+++ apr/apr/branches/1.5.x/locks/unix/proc_mutex.c Tue Apr 12 13:29:31 2016
@@ -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_me
 
 #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_pthr
             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_pthr
             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_pthr
 
     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_pthr
         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_pthr
     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_pthr
 #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_pthr
         /* 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_me
     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"
 };