From: Stefan Fritsch Date: Sat, 19 Jun 2010 09:10:54 +0000 (+0000) Subject: Add deferred write pool to core_output_filter to clean up file descriptors as X-Git-Tag: 2.3.7~164 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6b2857259b04d9a293b8f3af5c5b7f7103439cf6;p=apache Add deferred write pool to core_output_filter to clean up file descriptors as soon as the corresponding response has been sent and not only after the connection has been closed. This change does not deal with pipelined requests, yet. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@956202 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/ap_mmn.h b/include/ap_mmn.h index fca4850c40..89cca6cc10 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -229,6 +229,7 @@ * ap_recent_ctime_ex(). * 20100609.0 (2.3.6-dev) Dropped ap_args_to_table due to missing constraints. * 20100609.1 (2.3.7-dev) Introduce ap_log_cserror() + * 20100609.2 (2.3.7-dev) Add deferred write pool to core_output_filter_ctx */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -236,7 +237,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20100609 #endif -#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/httpd.h b/include/httpd.h index c31a6f4562..32ee4986ed 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -1261,6 +1261,7 @@ typedef struct core_output_filter_ctx { apr_size_t bytes_in; apr_size_t bytes_written; apr_bucket_brigade *tmp_flush_bb; + apr_pool_t *deferred_write_pool; } core_output_filter_ctx_t; typedef struct core_filter_ctx { diff --git a/server/core_filters.c b/server/core_filters.c index bfc830f904..46848f5153 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -383,6 +383,8 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb) * allocated from bb->pool which might be wrong. */ ctx->tmp_flush_bb = apr_brigade_create(c->pool, c->bucket_alloc); + /* same for buffered_bb and ap_save_brigade */ + ctx->buffered_bb = apr_brigade_create(c->pool, c->bucket_alloc); } if (new_bb != NULL) { @@ -512,6 +514,10 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb) return APR_SUCCESS; } +/* + * This function assumes that either ctx->buffered_bb == NULL, or + * ctx->buffered_bb is empty, or ctx->buffered_bb == bb + */ static void setaside_remaining_output(ap_filter_t *f, core_output_filter_ctx_t *ctx, apr_bucket_brigade *bb, @@ -524,13 +530,22 @@ static void setaside_remaining_output(ap_filter_t *f, if (!APR_BRIGADE_EMPTY(bb)) { c->data_in_output_filters = 1; if (bb != ctx->buffered_bb) { - /* XXX should this use a separate deferred write pool, like - * the original ap_core_output_filter? - */ - ap_save_brigade(f, &(ctx->buffered_bb), &bb, c->pool); + if (!ctx->deferred_write_pool) { + apr_pool_create(&ctx->deferred_write_pool, c->pool); + apr_pool_tag(ctx->deferred_write_pool, "deferred_write"); + } + ap_save_brigade(f, &(ctx->buffered_bb), &bb, + ctx->deferred_write_pool); apr_brigade_cleanup(bb); } } + else if (ctx->deferred_write_pool) { + /* + * There are no more requests in the pipeline. We can just clear the + * pool. + */ + apr_pool_clear(ctx->deferred_write_pool); + } } #ifndef APR_MAX_IOVEC_SIZE