summaryrefslogtreecommitdiff
path: root/memory
diff options
context:
space:
mode:
authorstriker <striker@13f79535-47bb-0310-9956-ffa450edef68>2002-01-14 09:18:40 +0000
committerstriker <striker@13f79535-47bb-0310-9956-ffa450edef68>2002-01-14 09:18:40 +0000
commitd44a9b7b7bc89db04184fee4cdcd51b8b1cd4ef5 (patch)
treec10d088ed42510b010125754a075c0103d5fedfe /memory
parentd3b2b4a7fb922c4147afa336a6d67a006fa488fa (diff)
downloadlibapr-d44a9b7b7bc89db04184fee4cdcd51b8b1cd4ef5.tar.gz
Fix the lifetime checking by locking the childlist before
traversing it. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@62782 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'memory')
-rw-r--r--memory/unix/apr_pools.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c
index fb3e347ca..8f5657690 100644
--- a/memory/unix/apr_pools.c
+++ b/memory/unix/apr_pools.c
@@ -888,31 +888,75 @@ APR_DECLARE(void) apr_pool_terminate(void)
* destroyed, in which case we abort().
*/
+#if APR_HAS_THREADS
+static int pool_is_child_of(apr_pool_t *pool, apr_pool_t *parent,
+ apr_thread_mutex_t *mutex)
+{
+ apr_pool_t *child;
+
+ if (parent == NULL)
+ return 0;
+
+#if APR_HAS_THREADS
+ if (parent->mutex && parent->mutex != mutex)
+ apr_thread_mutex_lock(parent->mutex);
+#endif
+
+ child = parent->child;
+
+ while (child) {
+ if (pool == child || pool_is_child_of(pool, child, parent->mutex)) {
+#if APR_HAS_THREADS
+ if (parent->mutex && parent->mutex != mutex)
+ apr_thread_mutex_unlock(parent->mutex);
+#endif
+
+ return 1;
+ }
+
+ child = child->sibling;
+ }
+
+#if APR_HAS_THREADS
+ if (parent->mutex && parent->mutex != mutex)
+ apr_thread_mutex_unlock(parent->mutex);
+#endif
+
+ return 0;
+}
+
+#else
static int pool_is_child_of(apr_pool_t *pool, apr_pool_t *parent)
{
apr_pool_t *child;
-
+
if (parent == NULL)
return 0;
child = parent->child;
while (child) {
- if (pool == child || pool_is_child_of(pool, child))
+ if (pool == child || pool_is_child_of(pool, child)) {
return 1;
-
+ }
+
child = child->sibling;
}
return 0;
}
+#endif
static void check_integrity(apr_pool_t *pool)
{
if (pool == global_pool || global_pool == NULL)
return;
+#if APR_HAS_THREADS
+ if (!pool_is_child_of(pool, global_pool, NULL))
+#else
if (!pool_is_child_of(pool, global_pool))
+#endif
{
#if defined(APR_POOL_DEBUG_VERBOSE)
if (file_stderr) {