From: Paul Querna Date: Thu, 17 Feb 2005 22:53:07 +0000 (+0000) Subject: *) include/httpd.h: Add a brigade for temporary uses in the core input filter context. X-Git-Tag: 2.1.3~15 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e2d4550b9ddbef27eb56e222a562ed1c5518732b;p=apache *) include/httpd.h: Add a brigade for temporary uses in the core input filter context. *) server/core_filters.c: Do not use brigade_split, since it allocates a new brigade. Instead move buckets to our tmpbb, and reuse the tmpbb for every call. PR: 33382 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@154200 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 1dec0b31ad..70bdbdb1a3 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,11 @@ Changes with Apache 2.1.3 [Remove entries to the current 2.0 section below, when backported] + *) core_input_filter: Move buckets to a persistent brigade instead of + creating a new brigade when apr_brigade_split is called. This stops + a memory leak when proxying a Streaming Media Server. PR 33382. + [Paul Querna] + *) mod_ssl: Add ssl_ext_lookup optional function for accessing certificate extensions. [David Reid, Joe Orton] diff --git a/include/httpd.h b/include/httpd.h index e66961c747..f0b81276c0 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -1143,6 +1143,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_filters.c b/server/core_filters.c index 88fee552fa..e5f5e340d8 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -109,6 +109,27 @@ 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); +} + int ap_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) @@ -138,7 +159,7 @@ int ap_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); APR_BRIGADE_INSERT_TAIL(ctx->b, e); @@ -290,8 +311,8 @@ int ap_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); @@ -312,7 +333,7 @@ int ap_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; }