Hi,

http://httpd.apache.org/docs/trunk/developer/output-filters.html recommends to reuse bucket brigades and to not use apr_brigade_destroy. However, both in 2.2 and in trunk, the core output filter sometimes calls apr_brigade_destroy on brigades that it has received down the chain from earlier output filters. Is this not bound to cause problems since the brigade's pool cleanup is then removed but the brigade is still reused later on?

Also, the core output filter often creates new brigades instead of reusing an existing brigade. This should also be changed to reduce memory usage, shouldn't it?

For trunk, the attached patch at least keeps the temporary brigade for flush buckets around. Do the versioning rules allow to add elements to core_output_filter_ctx for 2.2.x, too? It's defined in httpd.h.

Cheers,
Stefan
--- a/include/httpd.h
+++ b/include/httpd.h
@@ -1239,6 +1239,7 @@ struct server_rec {
 
 typedef struct core_output_filter_ctx {
     apr_bucket_brigade *buffered_bb;
+    apr_bucket_brigade *tmp_flush_bb;
     apr_size_t bytes_in;
     apr_size_t bytes_written;
 } core_output_filter_ctx_t;
diff --git a/server/core_filters.c b/server/core_filters.c
index d9b6eb0..093205a 100644
--- a/server/core_filters.c
+++ b/server/core_filters.c
@@ -468,7 +468,7 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
          bucket = next) {
         next = APR_BUCKET_NEXT(bucket);
         if (APR_BUCKET_IS_FLUSH(bucket)) {
-            apr_bucket_brigade *remainder = apr_brigade_split(bb, next);
+            ctx->tmp_flush_bb = apr_brigade_split_ex(bb, next, ctx->tmp_flush_bb);
             apr_status_t rv = send_brigade_blocking(net->client_socket, bb,
                                                     &(ctx->bytes_written), c);
             if (rv != APR_SUCCESS) {
@@ -476,7 +476,7 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
                 c->aborted = 1;
                 return rv;
             }
-            bb = remainder;
+            APR_BRIGADE_CONCAT(bb, ctx->tmp_flush_bb);
             next = APR_BRIGADE_FIRST(bb);
             bytes_in_brigade = 0;
             non_file_bytes_in_brigade = 0;

Reply via email to