From: Bill Stoddard Date: Wed, 17 Apr 2002 18:52:32 +0000 (+0000) Subject: Fix seg fault when garbage collecting an expired entry. remove_entity X-Git-Tag: 2.0.36~171 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=82e823ea906b34f7ba27ee84aee084b97f7df724;p=apache Fix seg fault when garbage collecting an expired entry. remove_entity should just remove the object from the cache and set the cleanup flag in the object. decrement_refcount will clean the object up when the refcount goes to zero. Defect reported by Jean-Jacques Clar at Novell. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@94683 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 1f5bab6a77..d3b162a9a0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,6 @@ Changes with Apache 2.0.36 + *) Fix segfault in mod_mem_cache when garabge collecting an expired + cache entry. [Bill Stoddard] *) Introduced -E startup_logfile_name option to httpd to allow admins to begin logging errors immediately. This provides Win32 users diff --git a/modules/experimental/mod_mem_cache.c b/modules/experimental/mod_mem_cache.c index 3865864dbb..6f25c86283 100644 --- a/modules/experimental/mod_mem_cache.c +++ b/modules/experimental/mod_mem_cache.c @@ -477,10 +477,14 @@ static int remove_entity(cache_handle_t *h) { cache_object_t *obj = h->cache_obj; - /* Remove the cache object from the cache */ + /* Remove the cache object from the cache under protection */ if (sconf->lock) { apr_thread_mutex_lock(sconf->lock); } + /* Set the cleanup flag. Object will be cleaned up (be decrement_refcount) + * when the refcount drops to zero. + */ + obj->cleanup = 1; obj = (cache_object_t *) apr_hash_get(sconf->cacheht, obj->key, APR_HASH_KEY_STRING); if (obj) { @@ -489,35 +493,11 @@ static int remove_entity(cache_handle_t *h) sconf->object_cnt--; sconf->cache_size -= mobj->m_len; } - else { - /* If the object was removed from the cache prior to this function being - * called, then obj == NULL. Reinit obj with the object being cleaned up. - * Note: This code assumes that there is at most only one object in the - * cache per key. - */ - obj = h->cache_obj; - } - - /* Cleanup the cache object - * Set obj->cleanup to ensure decrement_refcount cleans up the obj if it - * is still being referenced by another thread - */ - obj->cleanup = 1; -#ifndef USE_ATOMICS - obj->refcount--; - if (!obj->refcount) { - cleanup_cache_object(obj); - } -#endif if (sconf->lock) { apr_thread_mutex_unlock(sconf->lock); - } -#ifdef USE_ATOMICS - if (!apr_atomic_dec(&obj->refcount)) { - cleanup_cache_object(obj); } -#endif - h->cache_obj = NULL; + + h->cache_obj = NULL; return OK; } static apr_status_t serialize_table(cache_header_tbl_t **obj,