You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by mi...@apache.org on 2019/06/23 23:13:03 UTC
svn commit: r1861957 - in /apr/apr/trunk: CHANGES util-misc/apu_dso.c
Author: minfrin
Date: Sun Jun 23 23:13:03 2019
New Revision: 1861957
URL: http://svn.apache.org/viewvc?rev=1861957&view=rev
Log:
apu_dso_init: Fix pool lifetime and introduce a reference count.
apu_dso_init() can now be called more than once (from multiple
modules) and from unrelated pools (usually seen in unit tests).
Modified:
apr/apr/trunk/CHANGES
apr/apr/trunk/util-misc/apu_dso.c
Modified: apr/apr/trunk/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/trunk/CHANGES?rev=1861957&r1=1861956&r2=1861957&view=diff
==============================================================================
--- apr/apr/trunk/CHANGES [utf-8] (original)
+++ apr/apr/trunk/CHANGES [utf-8] Sun Jun 23 23:13:03 2019
@@ -1,6 +1,11 @@
-*- coding: utf-8 -*-
Changes for APR 2.0.0
+ *) apu_dso_init: Fix pool lifetime and introduce a reference count.
+ apu_dso_init() can now be called more than once (from multiple
+ modules) and from unrelated pools (usually seen in unit tests).
+ [Graham Leggett]
+
*) apr_crypto_openssl: use OPENSSL_init_crypto() to initialise OpenSSL
on versions 1.1+. [Graham Leggett]
Modified: apr/apr/trunk/util-misc/apu_dso.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/util-misc/apu_dso.c?rev=1861957&r1=1861956&r2=1861957&view=diff
==============================================================================
--- apr/apr/trunk/util-misc/apu_dso.c (original)
+++ apr/apr/trunk/util-misc/apu_dso.c Sun Jun 23 23:13:03 2019
@@ -37,7 +37,7 @@
static apr_thread_mutex_t* mutex = NULL;
#endif
static apr_hash_t *dsos = NULL;
-static apr_uint32_t initialised = 0, in_init = 1;
+static apr_uint32_t in_init = 0, initialised = 0;
#if APR_HAS_THREADS
apr_status_t apu_dso_mutex_lock()
@@ -59,11 +59,24 @@ apr_status_t apu_dso_mutex_unlock() {
static apr_status_t apu_dso_term(void *ptr)
{
- /* set statics to NULL so init can work again */
- dsos = NULL;
+ if (apr_atomic_inc32(&in_init)) {
+ while (apr_atomic_read32(&in_init) > 1); /* wait until we get fully inited */
+ }
+
+ /* Reference count - cleanup when last reference is cleaned up */
+ if (!apr_atomic_dec32(&initialised)) {
+ apr_pool_t *global = apr_hash_pool_get(dsos);
+
+ apr_pool_destroy(global);
+
+ /* set statics to NULL so init can work again */
+ dsos = NULL;
#if APR_HAS_THREADS
- mutex = NULL;
+ mutex = NULL;
#endif
+ }
+
+ apr_atomic_dec32(&in_init);
/* Everything else we need is handled by cleanups registered
* when we created mutexes and loaded DSOs
@@ -76,13 +89,22 @@ apr_status_t apu_dso_init(apr_pool_t *po
apr_status_t ret = APR_SUCCESS;
apr_pool_t *parent;
- if (apr_atomic_inc32(&initialised)) {
- apr_atomic_set32(&initialised, 1); /* prevent wrap-around */
+ if (apr_atomic_inc32(&in_init)) {
+ while (apr_atomic_read32(&in_init) > 1); /* wait until we get fully inited */
+ }
+
+ /* Reference count increment... */
+ if (!apr_atomic_inc32(&initialised)) {
+ apr_pool_t *global;
- while (apr_atomic_read32(&in_init)) /* wait until we get fully inited */
- ;
+ apr_pool_create_unmanaged(&global);
+ dsos = apr_hash_make(global);
+
+#if APR_HAS_THREADS
+ ret = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, global);
+ /* This already registers a pool cleanup */
+#endif
- return APR_SUCCESS;
}
/* Top level pool scope, need process-scope lifetime */
@@ -91,13 +113,7 @@ apr_status_t apu_dso_init(apr_pool_t *po
parent = apr_pool_parent_get(pool))
pool = parent;
- dsos = apr_hash_make(pool);
-
-#if APR_HAS_THREADS
- ret = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pool);
- /* This already registers a pool cleanup */
-#endif
-
+ /* ... to be decremented on cleanup */
apr_pool_cleanup_register(pool, NULL, apu_dso_term,
apr_pool_cleanup_null);