From: Jim Jagielski Date: Fri, 28 Aug 2009 14:42:29 +0000 (+0000) Subject: mod_mem_cache: fix seg fault under load due to pool concurrency problem X-Git-Tag: 2.2.14~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef9225a000efe7a1793b341a2fc7dfc15b0318b9;p=thirdparty%2Fapache%2Fhttpd.git mod_mem_cache: fix seg fault under load due to pool concurrency problem PR: 47672 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@808904 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 2a89d2139ff..946b2c8d29c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@  -*- coding: utf-8 -*- Changes with Apache 2.2.14 + *) mod_mem_cache: fix seg fault under load due to pool concurrency problem + PR: 47672 [Dan Poirier ] + *) mod_autoindex: Correctly create an empty cell if the description for a file is missing. PR 47682 [Peter Poeml ] diff --git a/STATUS b/STATUS index e10640ff53d..437eb47ebbd 100644 --- a/STATUS +++ b/STATUS @@ -89,12 +89,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_mem_cache: fix seg fault under load due to pool concurrency problem - PR: 47672 - Trunk Patch: n/a, mod_mem_cache is not in trunk - 2.2.x Patch: https://issues.apache.org/bugzilla/attachment.cgi?id=24124 - +1: poirier, minfrin, covener, jim - * mod_cache: Add CacheIgnoreURLSessionIdentifiers directive to ignore defined session identifiers encoded in the URL when caching. Trunk version of patch: diff --git a/modules/cache/mod_mem_cache.c b/modules/cache/mod_mem_cache.c index 7bdaeac9653..48bd785c50a 100644 --- a/modules/cache/mod_mem_cache.c +++ b/modules/cache/mod_mem_cache.c @@ -60,6 +60,7 @@ typedef enum { typedef struct mem_cache_object { apr_pool_t *pool; + apr_thread_mutex_t *lock; /* pools aren't thread-safe; use this lock when accessing this pool */ cache_type_e type; apr_table_t *header_out; apr_table_t *req_hdrs; /* for Vary negotiation */ @@ -91,6 +92,8 @@ typedef struct { } mem_cache_conf; static mem_cache_conf *sconf; +static int threaded_mpm; + #define DEFAULT_MAX_CACHE_SIZE 100*1024 #define DEFAULT_MIN_CACHE_OBJECT_SIZE 1 #define DEFAULT_MAX_CACHE_OBJECT_SIZE 10000 @@ -216,9 +219,8 @@ static void cleanup_cache_object(cache_object_t *obj) close(mobj->fd); #endif } + apr_pool_destroy(mobj->pool); } - - apr_pool_destroy(mobj->pool); } static apr_status_t decrement_refcount(void *arg) { @@ -359,6 +361,10 @@ static int create_entity(cache_handle_t *h, cache_type_e type_e, mobj = apr_pcalloc(pool, sizeof(*mobj)); mobj->pool = pool; + if (threaded_mpm) { + apr_thread_mutex_create(&mobj->lock, APR_THREAD_MUTEX_DEFAULT, pool); + } + /* Finish initing the cache object */ apr_atomic_set32(&obj->refcount, 1); mobj->total_refs = 1; @@ -601,7 +607,13 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info * - The original response headers (for returning with a cached response) * - The body of the message */ + if (mobj->lock) { + apr_thread_mutex_lock(mobj->lock); + } mobj->req_hdrs = deep_table_copy(mobj->pool, r->headers_in); + if (mobj->lock) { + apr_thread_mutex_unlock(mobj->lock); + } /* Precompute how much storage we need to hold the headers */ headers_out = apr_table_overlay(r->pool, r->headers_out, @@ -622,7 +634,13 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info r->content_encoding); } + if (mobj->lock) { + apr_thread_mutex_lock(mobj->lock); + } mobj->header_out = deep_table_copy(mobj->pool, headers_out); + if (mobj->lock) { + apr_thread_mutex_unlock(mobj->lock); + } /* Init the info struct */ obj->info.status = info->status; @@ -815,8 +833,6 @@ static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_bri static int mem_cache_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { - int threaded_mpm; - /* Sanity check the cache configuration */ if (sconf->min_cache_object_size >= sconf->max_cache_object_size) { ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,