]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* modules/http/http_request.c (ap_process_request_after_handler,
authorJoe Orton <jorton@apache.org>
Wed, 6 Jun 2018 11:39:33 +0000 (11:39 +0000)
committerJoe Orton <jorton@apache.org>
Wed, 6 Jun 2018 11:39:33 +0000 (11:39 +0000)
  ap_process_request): Cache and retrieve the brigade structure used
  to send EOR and FLUSH between requests in c->pool userdata, to avoid
  allocating a brigade structure per-request out of c->pool.

Submitted by: rpluem, jorton

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1833014 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/http/http_request.c

diff --git a/CHANGES b/CHANGES
index 19bfb979d94670f618f050b01fef446dcab33768..38caee5c5995bfde728117387f04ea8ad4140aec 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
 
+  *) http: Fix small memory leak per request when handling persistent
+     connections.  [Ruediger Pluem, Joe Orton]
+
   *) mod_remoteip: Fix RemoteIP{Trusted,Internal}ProxyList loading broken by 2.4.30.
      PR 62220.  [Chritophe Jaillet, Yann Ylavic]
 
index bb28d9c8ddf43e75c6799930cdf69d7445f1c2e0..20a75d4f087d8946d8293fc500222eb7c923be32 100644 (file)
@@ -345,6 +345,16 @@ AP_DECLARE(apr_status_t) ap_check_pipeline(conn_rec *c, apr_bucket_brigade *bb,
     return rv;
 }
 
+#define RETRIEVE_BRIGADE_FROM_POOL(bb, key, pool, allocator) do {       \
+    apr_pool_userdata_get((void **)&bb, key, pool);                     \
+    if (bb == NULL) {                                                   \
+        bb = apr_brigade_create(pool, allocator);                       \
+        apr_pool_userdata_setn((const void *)bb, key, NULL, pool);      \
+    }                                                                   \
+    else {                                                              \
+        apr_brigade_cleanup(bb);                                        \
+    }                                                                   \
+} while(0)
 
 AP_DECLARE(void) ap_process_request_after_handler(request_rec *r)
 {
@@ -358,7 +368,8 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r)
      * this bucket is destroyed, the request will be logged and
      * its pool will be freed
      */
-    bb = apr_brigade_create(c->pool, c->bucket_alloc);
+    RETRIEVE_BRIGADE_FROM_POOL(bb, "ap_process_request_after_handler_brigade",
+                               c->pool, c->bucket_alloc);
     b = ap_bucket_eor_create(c->bucket_alloc, r);
     APR_BRIGADE_INSERT_HEAD(bb, b);
 
@@ -402,7 +413,7 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r)
      */
     rv = ap_check_pipeline(c, bb, DEFAULT_LIMIT_BLANK_LINES);
     c->data_in_input_filters = (rv == APR_SUCCESS);
-    apr_brigade_destroy(bb);
+    apr_brigade_cleanup(bb);
 
     if (c->cs)
         c->cs->state = (c->aborted) ? CONN_STATE_LINGER
@@ -496,7 +507,8 @@ AP_DECLARE(void) ap_process_request(request_rec *r)
     ap_process_async_request(r);
 
     if (!c->data_in_input_filters || ap_run_input_pending(c) != OK) {
-        bb = apr_brigade_create(c->pool, c->bucket_alloc);
+        RETRIEVE_BRIGADE_FROM_POOL(bb, "ap_process_request_brigade", 
+                                   c->pool, c->bucket_alloc);
         b = apr_bucket_flush_create(c->bucket_alloc);
         APR_BRIGADE_INSERT_HEAD(bb, b);
         rv = ap_pass_brigade(c->output_filters, bb);
@@ -509,6 +521,7 @@ AP_DECLARE(void) ap_process_request(request_rec *r)
             ap_log_cerror(APLOG_MARK, APLOG_INFO, rv, c, APLOGNO(01581)
                           "flushing data to the client");
         }
+        apr_brigade_cleanup(bb);
     }
     if (ap_extended_status) {
         ap_time_process_request(c->sbh, STOP_PREQUEST);