diff options
author | striker <striker@13f79535-47bb-0310-9956-ffa450edef68> | 2002-01-14 09:18:40 +0000 |
---|---|---|
committer | striker <striker@13f79535-47bb-0310-9956-ffa450edef68> | 2002-01-14 09:18:40 +0000 |
commit | d44a9b7b7bc89db04184fee4cdcd51b8b1cd4ef5 (patch) | |
tree | c10d088ed42510b010125754a075c0103d5fedfe /memory | |
parent | d3b2b4a7fb922c4147afa336a6d67a006fa488fa (diff) | |
download | libapr-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.c | 50 |
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) { |