summaryrefslogtreecommitdiffstats
path: root/server/protocol.c
diff options
context:
space:
mode:
authorStefan Fritsch <sf@apache.org>2009-10-04 09:37:28 +0200
committerStefan Fritsch <sf@apache.org>2009-10-04 09:37:28 +0200
commitfbdde88b36bc806e4f79113f6d171d170af27849 (patch)
tree2d553ecf11f3201e56af0059d57d833c9ddaa62e /server/protocol.c
parentrefactor child status update functions to accommodate the addition of (diff)
downloadapache2-fbdde88b36bc806e4f79113f6d171d170af27849.tar.xz
apache2-fbdde88b36bc806e4f79113f6d171d170af27849.zip
core, mod_deflate, mod_sed: Reduce memory usage by reusing bucket
brigades in several places git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@821471 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--server/protocol.c59
1 files changed, 40 insertions, 19 deletions
diff --git a/server/protocol.c b/server/protocol.c
index e082de9390..85965d08bc 100644
--- a/server/protocol.c
+++ b/server/protocol.c
@@ -1251,6 +1251,7 @@ struct content_length_ctx {
* 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 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(
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 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(
* 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 @@ AP_DECLARE(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset,
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 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_old_write_filter(
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 @@ static apr_status_t buffer_output(request_rec *r,
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_NONSTD(int) ap_rvputs(request_rec *r, ...)
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;