On Sun, 13 Sep 2009, Ruediger Pluem wrote:
But your patch is causing core dumps during the proxy tests when
running the test suite :-(.
I currently don't understand why.


Hmmm... either ctx->tmp_flush_bb is NULL or, since it was added in the
middle of the struct, you didn't do a make distclean 1st....

That is not the problem. I did a slightly modified patch that added it to the
end. I suppose it has something to do with not matching pools or bucket
allocators between bb and ctx->tmp_flush_bb.
It fails on in the proxy case and in the proxy case we have some mixtures going
on there regarding pools and bucket allocators caused by the pooled backend
connections.

Yes, the lifetime of the brigade was wrong. The attached patch works without segfaults.

Cheers,
Stefan
diff --git a/include/httpd.h b/include/httpd.h
index a7a7025..cd47b11 100644
--- a/include/httpd.h
+++ b/include/httpd.h
@@ -1241,6 +1241,7 @@ typedef struct core_output_filter_ctx {
     apr_bucket_brigade *buffered_bb;
     apr_size_t bytes_in;
     apr_size_t bytes_written;
+    apr_bucket_brigade *tmp_flush_bb;
 } core_output_filter_ctx_t;
  
 typedef struct core_filter_ctx {
diff --git a/server/core_filters.c b/server/core_filters.c
index d9b6eb0..2f60d04 100644
--- a/server/core_filters.c
+++ b/server/core_filters.c
@@ -468,7 +468,15 @@ 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);
+            if (!ctx->tmp_flush_bb) {
+                /*
+                 * Need to create tmp brigade with correct lifetime. Passing
+                 * NULL to apr_brigade_split_ex would result in a brigade
+                 * allocated from a different pool.
+                 */
+                ctx->tmp_flush_bb = apr_brigade_create(c->pool, c->bucket_alloc);
+            }
+            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 +484,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