]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
mod_mem_cache: fix seg fault under load due to pool concurrency problem
authorJim Jagielski <jim@apache.org>
Fri, 28 Aug 2009 14:42:29 +0000 (14:42 +0000)
committerJim Jagielski <jim@apache.org>
Fri, 28 Aug 2009 14:42:29 +0000 (14:42 +0000)
PR: 47672

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@808904 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/cache/mod_mem_cache.c

diff --git a/CHANGES b/CHANGES
index 2a89d2139fff12a015a1296ff5d99d05206e76ea..946b2c8d29ce7d67941c520e4b1ae130d9a39625 100644 (file)
--- 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 <poirier pobox.com>]
+
   *) mod_autoindex: Correctly create an empty cell if the description
      for a file is missing. PR 47682 [Peter Poeml <poeml suse.de>]
 
diff --git a/STATUS b/STATUS
index e10640ff53dabc50e7a6dfbb1a1c54234b14ce3d..437eb47ebbdef0ed0aa2ea70887b13c79df94e71 100644 (file)
--- 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:
index 7bdaeac96532c2794d1f05e9a894668f7e21c0bb..48bd785c50a5e4a6048f690f1a42b15b713890ec 100644 (file)
@@ -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,