You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2009/10/04 09:37:28 UTC
svn commit: r821471 - in /httpd/httpd/trunk: CHANGES
modules/filters/mod_deflate.c modules/filters/mod_sed.c
modules/http/chunk_filter.c server/protocol.c
Author: sf
Date: Sun Oct 4 07:37:28 2009
New Revision: 821471
URL: http://svn.apache.org/viewvc?rev=821471&view=rev
Log:
core, mod_deflate, mod_sed: Reduce memory usage by reusing bucket
brigades in several places
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/modules/filters/mod_deflate.c
httpd/httpd/trunk/modules/filters/mod_sed.c
httpd/httpd/trunk/modules/http/chunk_filter.c
httpd/httpd/trunk/server/protocol.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=821471&r1=821470&r2=821471&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sun Oct 4 07:37:28 2009
@@ -10,6 +10,9 @@
mod_proxy_ftp: NULL pointer dereference on error paths.
[Stefan Fritsch <sf fritsch.de>, Joe Orton]
+ *) core, mod_deflate, mod_sed: Reduce memory usage by reusing bucket
+ brigades in several places. [Stefan Fritsch]
+
*) mod_cache: Fix uri_meets_conditions() so that CacheEnable will
match by scheme, or by a wildcarded hostname. PR 40169
[Ryan Pendergast <rpender us.ibm.com>, Graham Leggett]
Modified: httpd/httpd/trunk/modules/filters/mod_deflate.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_deflate.c?rev=821471&r1=821470&r2=821471&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_deflate.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_deflate.c Sun Oct 4 07:37:28 2009
@@ -1011,14 +1011,11 @@
}
if (!APR_BRIGADE_EMPTY(ctx->proc_bb)) {
- apr_bucket_brigade *newbb;
-
/* May return APR_INCOMPLETE which is fine by us. */
apr_brigade_partition(ctx->proc_bb, readbytes, &bkt);
- newbb = apr_brigade_split(ctx->proc_bb, bkt);
APR_BRIGADE_CONCAT(bb, ctx->proc_bb);
- APR_BRIGADE_CONCAT(ctx->proc_bb, newbb);
+ apr_brigade_split_ex(bb, bkt, ctx->proc_bb);
}
return APR_SUCCESS;
Modified: httpd/httpd/trunk/modules/filters/mod_sed.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_sed.c?rev=821471&r1=821470&r2=821471&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_sed.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_sed.c Sun Oct 4 07:37:28 2009
@@ -48,6 +48,7 @@
ap_filter_t *f;
request_rec *r;
apr_bucket_brigade *bb;
+ apr_bucket_brigade *bbinp;
char *outbuf;
char *curoutbuf;
int bufsize;
@@ -392,6 +393,7 @@
&sed_module);
sed_filter_ctxt *ctx = f->ctx;
apr_status_t status;
+ apr_bucket_brigade *bbinp;
sed_expr_config *sed_cfg = &cfg->input;
if (mode != AP_MODE_READBYTES) {
@@ -413,9 +415,12 @@
if (status != APR_SUCCESS)
return status;
ctx = f->ctx;
- ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+ ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+ ctx->bbinp = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
}
+ bbinp = ctx->bbinp;
+
/* Here is the logic :
* Read the readbytes data from next level fiter into bbinp. Loop through
* the buckets in bbinp and read the data from buckets and invoke
@@ -435,11 +440,10 @@
* the question is where to add it?
*/
while (APR_BRIGADE_EMPTY(ctx->bb)) {
- apr_bucket_brigade *bbinp;
apr_bucket *b;
/* read the bytes from next level filter */
- bbinp = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+ apr_brigade_cleanup(bbinp);
status = ap_get_brigade(f->next, bbinp, mode, block, readbytes);
if (status != APR_SUCCESS) {
return status;
@@ -469,20 +473,16 @@
flush_output_buffer(ctx);
}
}
- apr_brigade_cleanup(bbinp);
- apr_brigade_destroy(bbinp);
}
if (!APR_BRIGADE_EMPTY(ctx->bb)) {
- apr_bucket_brigade *newbb = NULL;
apr_bucket *b = NULL;
/* This may return APR_INCOMPLETE which should be fine */
apr_brigade_partition(ctx->bb, readbytes, &b);
- newbb = apr_brigade_split(ctx->bb, b);
APR_BRIGADE_CONCAT(bb, ctx->bb);
- APR_BRIGADE_CONCAT(ctx->bb, newbb);
+ apr_brigade_split_ex(bb, b, ctx->bb);
}
return APR_SUCCESS;
}
Modified: httpd/httpd/trunk/modules/http/chunk_filter.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http/chunk_filter.c?rev=821471&r1=821470&r2=821471&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http/chunk_filter.c (original)
+++ httpd/httpd/trunk/modules/http/chunk_filter.c Sun Oct 4 07:37:28 2009
@@ -49,11 +49,11 @@
#define ASCII_CRLF "\015\012"
#define ASCII_ZERO "\060"
conn_rec *c = f->r->connection;
- apr_bucket_brigade *more;
+ apr_bucket_brigade *more, *tmp;
apr_bucket *e;
apr_status_t rv;
- for (more = NULL; b; b = more, more = NULL) {
+ for (more = tmp = NULL; b; b = more, more = NULL) {
apr_off_t bytes = 0;
apr_bucket *eos = NULL;
apr_bucket *flush = NULL;
@@ -85,7 +85,7 @@
if (APR_BUCKET_IS_FLUSH(e)) {
flush = e;
if (e != APR_BRIGADE_LAST(b)) {
- more = apr_brigade_split(b, APR_BUCKET_NEXT(e));
+ more = apr_brigade_split_ex(b, APR_BUCKET_NEXT(e), tmp);
}
break;
}
@@ -105,7 +105,7 @@
* block so we pass down what we have so far.
*/
bytes += len;
- more = apr_brigade_split(b, APR_BUCKET_NEXT(e));
+ more = apr_brigade_split_ex(b, APR_BUCKET_NEXT(e), tmp);
break;
}
else {
@@ -189,6 +189,8 @@
if (rv != APR_SUCCESS || eos != NULL) {
return rv;
}
+ tmp = b;
+ apr_brigade_cleanup(tmp);
}
return APR_SUCCESS;
}
Modified: httpd/httpd/trunk/server/protocol.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?rev=821471&r1=821470&r2=821471&view=diff
==============================================================================
--- httpd/httpd/trunk/server/protocol.c (original)
+++ httpd/httpd/trunk/server/protocol.c Sun Oct 4 07:37:28 2009
@@ -1251,6 +1251,7 @@
* least one bucket on to the next output filter
* for this request
*/
+ apr_bucket_brigade *tmpbb;
};
/* This filter computes the content length, but it also computes the number
@@ -1271,6 +1272,7 @@
if (!ctx) {
f->ctx = ctx = apr_palloc(r->pool, sizeof(*ctx));
ctx->data_sent = 0;
+ ctx->tmpbb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
}
/* Loop through this set of buckets to compute their length
@@ -1300,16 +1302,15 @@
* do a blocking read on the next batch.
*/
if (e != APR_BRIGADE_FIRST(b)) {
- apr_bucket_brigade *split = apr_brigade_split(b, e);
+ apr_brigade_split_ex(b, e, ctx->tmpbb);
apr_bucket *flush = apr_bucket_flush_create(r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(b, flush);
rv = ap_pass_brigade(f->next, b);
if (rv != APR_SUCCESS || f->c->aborted) {
- apr_brigade_destroy(split);
return rv;
}
- b = split;
+ APR_BRIGADE_CONCAT(b, ctx->tmpbb);
e = APR_BRIGADE_FIRST(b);
ctx->data_sent = 1;
@@ -1402,6 +1403,7 @@
typedef struct {
apr_bucket_brigade *bb;
+ apr_bucket_brigade *tmpbb;
} old_write_filter_ctx;
AP_CORE_DECLARE_NONSTD(apr_status_t) ap_old_write_filter(
@@ -1422,16 +1424,11 @@
return ap_pass_brigade(f->next, bb);
}
-static apr_status_t buffer_output(request_rec *r,
- const char *str, apr_size_t len)
+static ap_filter_t *insert_old_write_filter(request_rec *r)
{
- conn_rec *c = r->connection;
ap_filter_t *f;
old_write_filter_ctx *ctx;
- if (len == 0)
- return APR_SUCCESS;
-
/* future optimization: record some flags in the request_rec to
* say whether we've added our filter, and whether it is first.
*/
@@ -1445,24 +1442,41 @@
if (f == NULL) {
/* our filter hasn't been added yet */
ctx = apr_pcalloc(r->pool, sizeof(*ctx));
+ ctx->tmpbb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+
ap_add_output_filter("OLD_WRITE", ctx, r, r->connection);
f = r->output_filters;
}
+ return f;
+}
+
+static apr_status_t buffer_output(request_rec *r,
+ const char *str, apr_size_t len)
+{
+ conn_rec *c = r->connection;
+ ap_filter_t *f;
+ old_write_filter_ctx *ctx;
+
+ if (len == 0)
+ return APR_SUCCESS;
+
+ f = insert_old_write_filter(r);
+ ctx = f->ctx;
+
/* if the first filter is not our buffering filter, then we have to
* deliver the content through the normal filter chain
*/
if (f != r->output_filters) {
- apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc);
+ apr_status_t rv;
apr_bucket *b = apr_bucket_transient_create(str, len, c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, b);
+ APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, b);
- return ap_pass_brigade(r->output_filters, bb);
+ rv = ap_pass_brigade(r->output_filters, ctx->tmpbb);
+ apr_brigade_cleanup(ctx->tmpbb);
+ return rv;
}
- /* grab the context from our filter */
- ctx = r->output_filters->ctx;
-
if (ctx->bb == NULL) {
ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc);
}
@@ -1617,13 +1631,20 @@
AP_DECLARE(int) ap_rflush(request_rec *r)
{
conn_rec *c = r->connection;
- apr_bucket_brigade *bb;
apr_bucket *b;
+ ap_filter_t *f;
+ old_write_filter_ctx *ctx;
+ apr_status_t rv;
+
+ f = insert_old_write_filter(r);
+ ctx = f->ctx;
- bb = apr_brigade_create(r->pool, c->bucket_alloc);
b = apr_bucket_flush_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, b);
- if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS)
+ APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, b);
+
+ rv = ap_pass_brigade(r->output_filters, ctx->tmpbb);
+ apr_brigade_cleanup(ctx->tmpbb);
+ if (rv != APR_SUCCESS)
return -1;
return 0;
Re: svn commit: r821471 - in /httpd/httpd/trunk: CHANGES modules/filters/mod_deflate.c modules/filters/mod_sed.c modules/http/chunk_filter.c server/protocol.c
Posted by Stefan Fritsch <sf...@sfritsch.de>.
On Sunday 04 October 2009, Ruediger Pluem wrote:
> To be on the safe side we should do apr_brigade_cleanup(b) here.
>
Thanks. Fixed in r821481
Re: svn commit: r821471 - in /httpd/httpd/trunk: CHANGES modules/filters/mod_deflate.c
modules/filters/mod_sed.c modules/http/chunk_filter.c server/protocol.c
Posted by Ruediger Pluem <rp...@apache.org>.
On 10/04/2009 09:37 AM, sf@apache.org wrote:
> Author: sf
> Date: Sun Oct 4 07:37:28 2009
> New Revision: 821471
>
> URL: http://svn.apache.org/viewvc?rev=821471&view=rev
> Log:
> core, mod_deflate, mod_sed: Reduce memory usage by reusing bucket
> brigades in several places
>
> Modified:
> httpd/httpd/trunk/CHANGES
> httpd/httpd/trunk/modules/filters/mod_deflate.c
> httpd/httpd/trunk/modules/filters/mod_sed.c
> httpd/httpd/trunk/modules/http/chunk_filter.c
> httpd/httpd/trunk/server/protocol.c
>
> Modified: httpd/httpd/trunk/server/protocol.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?rev=821471&r1=821470&r2=821471&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/server/protocol.c (original)
> +++ httpd/httpd/trunk/server/protocol.c Sun Oct 4 07:37:28 2009
> @@ -1300,16 +1302,15 @@
> * do a blocking read on the next batch.
> */
> if (e != APR_BRIGADE_FIRST(b)) {
> - apr_bucket_brigade *split = apr_brigade_split(b, e);
> + apr_brigade_split_ex(b, e, ctx->tmpbb);
> apr_bucket *flush = apr_bucket_flush_create(r->connection->bucket_alloc);
>
> APR_BRIGADE_INSERT_TAIL(b, flush);
> rv = ap_pass_brigade(f->next, b);
> if (rv != APR_SUCCESS || f->c->aborted) {
> - apr_brigade_destroy(split);
> return rv;
> }
> - b = split;
To be on the safe side we should do apr_brigade_cleanup(b) here.
> + APR_BRIGADE_CONCAT(b, ctx->tmpbb);
> e = APR_BRIGADE_FIRST(b);
>
> ctx->data_sent = 1;
Regards
RĂ¼diger