From: Stefan Eissing Date: Thu, 24 Mar 2016 16:47:26 +0000 (+0000) Subject: Merge of 1736463 from trunk: X-Git-Tag: 2.4.20~31 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=08928f8f16a13e15b992cc9312f61deaddbd20a5;p=apache Merge of 1736463 from trunk: mod_http2: fix for scoreboard updates missing, mem leak fix for slave connections git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1736465 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 80353a741b..58033bfb7a 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.20 + *) mod_http2: fix for missing score board updates on request count, fix for + memory leak on slave connection reuse. + *) mod_http2: Fix build on Windows from dsp files. [Stefan Eissing] diff --git a/modules/http2/h2_io.c b/modules/http2/h2_io.c index 0beb85606d..3b36ca181e 100644 --- a/modules/http2/h2_io.c +++ b/modules/http2/h2_io.c @@ -425,16 +425,6 @@ apr_status_t h2_io_out_write(h2_io *io, apr_bucket_brigade *bb, return APR_ECONNABORTED; } - if (io->eos_out) { - apr_off_t len = 0; - /* We have already delivered an EOS bucket to a reader, no - * sense in storing anything more here. - */ - apr_brigade_length(bb, 0, &len); - apr_brigade_cleanup(bb); - return (len > 0)? APR_EOF : APR_SUCCESS; - } - /* Filter the EOR bucket and set it aside. We prefer to tear down * the request when the whole h2 stream is done */ for (b = APR_BRIGADE_FIRST(bb); diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c index 5c2319ce94..00a64ecf2a 100644 --- a/modules/http2/h2_mplx.c +++ b/modules/http2/h2_mplx.c @@ -279,6 +279,8 @@ static int io_out_consumed_signal(h2_mplx *m, h2_io *io) static void io_destroy(h2_mplx *m, h2_io *io, int events) { + int reuse_slave; + /* cleanup any buffered input */ h2_io_in_shutdown(io); if (events) { @@ -297,12 +299,16 @@ static void io_destroy(h2_mplx *m, h2_io *io, int events) h2_io_set_remove(m->redo_ios, io); } + reuse_slave = ((m->spare_slaves->nelts < m->spare_slaves->nalloc) + && !io->rst_error && io->eor); if (io->task) { conn_rec *slave = io->task->c; h2_task_destroy(io->task); io->task = NULL; - if (m->spare_slaves->nelts < m->spare_slaves->nalloc) { + if (reuse_slave) { + apr_bucket_delete(io->eor); + io->eor = NULL; APR_ARRAY_PUSH(m->spare_slaves, conn_rec*) = slave; } else { @@ -310,10 +316,6 @@ static void io_destroy(h2_mplx *m, h2_io *io, int events) } } - if (io->eor) { - apr_bucket_delete(io->eor); - io->eor = NULL; - } if (io->pool) { apr_pool_destroy(io->pool); } @@ -1121,6 +1123,8 @@ h2_task *h2_mplx_pop_task(h2_mplx *m, int *has_more) static void task_done(h2_mplx *m, h2_task *task, h2_req_engine *ngn) { if (task) { + h2_io *io = h2_io_set_get(m->stream_ios, task->stream_id); + if (task->frozen) { /* this task was handed over to an engine for processing * and the original worker has finished. That means the @@ -1133,8 +1137,6 @@ static void task_done(h2_mplx *m, h2_task *task, h2_req_engine *ngn) apr_thread_cond_broadcast(m->task_thawed); } else { - h2_io *io = h2_io_set_get(m->stream_ios, task->stream_id); - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, "h2_mplx(%ld): task(%s) done", m->id, task->id); /* clean our references and report request as done. Signal diff --git a/modules/http2/h2_task.c b/modules/http2/h2_task.c index b273a05c2b..9fa69b2365 100644 --- a/modules/http2/h2_task.c +++ b/modules/http2/h2_task.c @@ -269,7 +269,6 @@ static apr_status_t h2_task_process_request(h2_task *task, conn_rec *c) "h2_task(%s): create request_rec failed, r->status=%d", task->id, r->status); } - c->sbh = NULL; return APR_SUCCESS; } diff --git a/modules/http2/h2_task_output.c b/modules/http2/h2_task_output.c index a15a80cf71..959398d1d1 100644 --- a/modules/http2/h2_task_output.c +++ b/modules/http2/h2_task_output.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "h2_private.h" #include "h2_conn.h" @@ -136,6 +137,7 @@ static apr_status_t write_brigade_raw(h2_task_output *output, apr_status_t h2_task_output_write(h2_task_output *output, ap_filter_t* f, apr_bucket_brigade* bb) { + apr_bucket *b; apr_status_t status = APR_SUCCESS; if (APR_BRIGADE_EMPTY(bb)) { @@ -147,6 +149,16 @@ apr_status_t h2_task_output_write(h2_task_output *output, if (output->task->frozen) { h2_util_bb_log(output->task->c, output->task->stream_id, APLOG_TRACE2, "frozen task output write, ignored", bb); + while (!APR_BRIGADE_EMPTY(bb)) { + b = APR_BRIGADE_FIRST(bb); + if (AP_BUCKET_IS_EOR(b)) { + /* TODO: keep it */ + APR_BUCKET_REMOVE(b); + } + else { + apr_bucket_delete(b); + } + } return APR_SUCCESS; } diff --git a/modules/http2/h2_version.h b/modules/http2/h2_version.h index 836aa07468..1b961c51e7 100644 --- a/modules/http2/h2_version.h +++ b/modules/http2/h2_version.h @@ -26,7 +26,7 @@ * @macro * Version number of the http2 module as c string */ -#define MOD_HTTP2_VERSION "1.4.4" +#define MOD_HTTP2_VERSION "1.4.5" /** * @macro @@ -34,7 +34,7 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define MOD_HTTP2_VERSION_NUM 0x010404 +#define MOD_HTTP2_VERSION_NUM 0x010405 #endif /* mod_h2_h2_version_h */