]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
core_input_filter: Stop leaking a brigade by moving buckets to an existing brigade...
authorPaul Querna <pquerna@apache.org>
Sat, 26 Feb 2005 09:04:10 +0000 (09:04 +0000)
committerPaul Querna <pquerna@apache.org>
Sat, 26 Feb 2005 09:04:10 +0000 (09:04 +0000)
PR: 33382
Reviewed By: Justin Erenkrantz, Jeff Trawick

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

CHANGES
STATUS
include/httpd.h
server/core.c

diff --git a/CHANGES b/CHANGES
index f9c0f4c11b1cdc8f970f9107920a16f46197ec8d..4c19dc719242dfb905990b338f7032b151d64227 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
 Changes with Apache 2.0.54
 
+  *) core_input_filter: Move buckets to a persistent brigade instead of
+     creating a new brigade. This stop a memory leak when proxying a 
+     Streaming Media Server. PR 33382. [Paul Querna]
+
   *) mod_win32: Ignore both PATH_INFO as well as PATH_TRANSLATED to avoid 
      hiccups from additional path information passed in non-utf-8 format.
      [Richard Donkin <rd9 donkin.org]
diff --git a/STATUS b/STATUS
index 95547ef9e593f537e23b9c012008ce3fb552b5ac..40f55ee4bc91050515c262594fc02c4b3b673f80 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -94,12 +94,6 @@ PATCHES TO BACKPORT FROM TRUNK:
     identify exactly what the proposed changes are! ]
   [ please append new backports at the end of this list not the top. ]
 
-    *) core_input_filter: Fix leak of a brigade by moving buckets to an 
-       existing brigade instead of calling brigade_split which creates a 
-       new brigade. PR 33382. r154200
-       Patch for 2.0: http://www.apache.org/~pquerna/c-i-f-leak.patch
-       +1: pquerna, trawick, jerenkrantz
-
     *) mod_ssl: Set r->user from SSLUsername earlier so that it's
        actually useful.
        http://svn.apache.org/viewcvs.cgi?rev=153280&view=rev
index 4ebc558dda14ec13f209243b406213f0c7ff2f2f..16dad6cae6c649495a4462c9cbf33a807b74738e 100644 (file)
@@ -1100,6 +1100,7 @@ typedef struct core_output_filter_ctx {
  
 typedef struct core_filter_ctx {
     apr_bucket_brigade *b;
+    apr_bucket_brigade *tmpbb;
 } core_ctx_t;
  
 typedef struct core_net_rec {
index 6955911b357ceeb439d01f37ec807ac596662f96..fbc1763ac716bec8cb001d6db8547a73a08b33f3 100644 (file)
@@ -3674,6 +3674,28 @@ do { \
     } while (!APR_BRIGADE_EMPTY(b) && (e != APR_BRIGADE_SENTINEL(b))); \
 } while (0)
 
+
+/**
+ * Split the contents of a brigade after bucket 'e' to an existing brigade
+ *
+ * XXXX: Should this function be added to APR-Util?
+ */
+static void brigade_move(apr_bucket_brigade *b, apr_bucket_brigade *a,
+                         apr_bucket *e)
+{
+    apr_bucket *f;     
+
+    if (e != APR_BRIGADE_SENTINEL(b)) {
+        f = APR_RING_LAST(&b->list);
+        APR_RING_UNSPLICE(e, f, link);
+        APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link);
+    }
+
+    APR_BRIGADE_CHECK_CONSISTENCY(a);
+    APR_BRIGADE_CHECK_CONSISTENCY(b);
+}
+
+
 static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
                              ap_input_mode_t mode, apr_read_type_e block,
                              apr_off_t readbytes)
@@ -3703,6 +3725,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
     {
         ctx = apr_pcalloc(f->c->pool, sizeof(*ctx));
         ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
+        ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc);
 
         /* seed the brigade with the client socket. */
         e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc);
@@ -3814,7 +3837,6 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
     /* read up to the amount they specified. */
     if (mode == AP_MODE_READBYTES || mode == AP_MODE_SPECULATIVE) {
         apr_bucket *e;
-        apr_bucket_brigade *newbb;
 
         AP_DEBUG_ASSERT(readbytes > 0);
 
@@ -3855,8 +3877,8 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
             return rv;
         }
 
-        /* Must do split before CONCAT */
-        newbb = apr_brigade_split(ctx->b, e);
+        /* Must do move before CONCAT */
+        brigade_move(ctx->b, ctx->tmpbb, e);
 
         if (mode == AP_MODE_READBYTES) {
             APR_BRIGADE_CONCAT(b, ctx->b);
@@ -3873,7 +3895,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
         }
 
         /* Take what was originally there and place it back on ctx->b */
-        APR_BRIGADE_CONCAT(ctx->b, newbb);
+        APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb);
     }
     return APR_SUCCESS;
 }