From: Paul Querna Date: Sat, 26 Feb 2005 09:04:10 +0000 (+0000) Subject: core_input_filter: Stop leaking a brigade by moving buckets to an existing brigade... X-Git-Tag: 2.0.54~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8036d56b33fa447f13fdcc158c596d0ffcaf8e10;p=thirdparty%2Fapache%2Fhttpd.git core_input_filter: Stop leaking a brigade by moving buckets to an existing brigade instead of calling brigade_split. 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 --- diff --git a/CHANGES b/CHANGES index f9c0f4c11b1..4c19dc71924 100644 --- 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 user from SSLUsername earlier so that it's actually useful. http://svn.apache.org/viewcvs.cgi?rev=153280&view=rev diff --git a/include/httpd.h b/include/httpd.h index 4ebc558dda1..16dad6cae6c 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -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 { diff --git a/server/core.c b/server/core.c index 6955911b357..fbc1763ac71 100644 --- a/server/core.c +++ b/server/core.c @@ -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; }