You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2016/06/09 10:28:51 UTC
svn commit: r1747531 - in /httpd/httpd/trunk: CHANGES
modules/http2/h2_bucket_beam.c modules/http2/h2_bucket_beam.h
modules/http2/h2_mplx.c modules/http2/h2_stream.c
Author: icing
Date: Thu Jun 9 10:28:51 2016
New Revision: 1747531
URL: http://svn.apache.org/viewvc?rev=1747531&view=rev
Log:
mod_http2: more orderly destruction of stream/task pairs
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/modules/http2/h2_bucket_beam.c
httpd/httpd/trunk/modules/http2/h2_bucket_beam.h
httpd/httpd/trunk/modules/http2/h2_mplx.c
httpd/httpd/trunk/modules/http2/h2_stream.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1747531&r1=1747530&r2=1747531&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Thu Jun 9 10:28:51 2016
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.0
+ *) mod_http2: more orderly destruction of stream/task pairs, addressing
+ reported crashes on aborted connections. [Stefan Eissing]
+
*) mod_dav: Add support for childtags to dav_error.
[Jari Urpalainen <jari.urpalainen nokia.com>]
Modified: httpd/httpd/trunk/modules/http2/h2_bucket_beam.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_bucket_beam.c?rev=1747531&r1=1747530&r2=1747531&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_bucket_beam.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_bucket_beam.c Thu Jun 9 10:28:51 2016
@@ -407,6 +407,12 @@ static apr_status_t beam_cleanup(void *d
r_purge_reds(beam);
h2_blist_cleanup(&beam->red);
report_consumption(beam, 0);
+ while (!H2_BPROXY_LIST_EMPTY(&beam->proxies)) {
+ h2_beam_proxy *proxy = H2_BPROXY_LIST_FIRST(&beam->proxies);
+ H2_BPROXY_REMOVE(proxy);
+ proxy->beam = NULL;
+ proxy->bred = NULL;
+ }
h2_blist_cleanup(&beam->purge);
h2_blist_cleanup(&beam->hold);
@@ -534,16 +540,18 @@ apr_status_t h2_beam_close(h2_bucket_bea
return beam->aborted? APR_ECONNABORTED : APR_SUCCESS;
}
-apr_status_t h2_beam_shutdown(h2_bucket_beam *beam, apr_read_type_e block)
+apr_status_t h2_beam_shutdown(h2_bucket_beam *beam, apr_read_type_e block,
+ int clear_buffers)
{
apr_status_t status;
h2_beam_lock bl;
if ((status = enter_yellow(beam, &bl)) == APR_SUCCESS) {
- r_purge_reds(beam);
- h2_blist_cleanup(&beam->red);
+ if (clear_buffers) {
+ r_purge_reds(beam);
+ h2_blist_cleanup(&beam->red);
+ }
beam_close(beam);
- report_consumption(beam, 0);
while (status == APR_SUCCESS
&& (!H2_BPROXY_LIST_EMPTY(&beam->proxies)
Modified: httpd/httpd/trunk/modules/http2/h2_bucket_beam.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_bucket_beam.h?rev=1747531&r1=1747530&r2=1747531&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_bucket_beam.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_bucket_beam.h Thu Jun 9 10:28:51 2016
@@ -282,16 +282,17 @@ void h2_beam_abort(h2_bucket_beam *beam)
apr_status_t h2_beam_close(h2_bucket_beam *beam);
/**
- * Empty any buffered data and return APR_SUCCESS when all buckets
- * in transit have been handled. When called with APR_BLOCK_READ and
- * with a mutex installed, will wait until this is the case. Otherwise
- * APR_EAGAIN is returned.
+ * Return APR_SUCCESS when all buckets in transit have been handled.
+ * When called with APR_BLOCK_READ and a mutex set, will wait until the green
+ * side has consumed all data. Otherwise APR_EAGAIN is returned.
+ * With clear_buffers set, any queued data is discarded.
* If a timeout is set on the beam, waiting might also time out and
* return APR_ETIMEUP.
*
* Call from the red side only.
*/
-apr_status_t h2_beam_shutdown(h2_bucket_beam *beam, apr_read_type_e block);
+apr_status_t h2_beam_shutdown(h2_bucket_beam *beam, apr_read_type_e block,
+ int clear_buffers);
void h2_beam_mutex_set(h2_bucket_beam *beam,
h2_beam_mutex_enter m_enter,
Modified: httpd/httpd/trunk/modules/http2/h2_mplx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.c?rev=1747531&r1=1747530&r2=1747531&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.c Thu Jun 9 10:28:51 2016
@@ -200,7 +200,7 @@ static int purge_stream(void *ctx, void
h2_ihash_remove(m->spurge, stream->id);
h2_stream_destroy(stream);
if (task) {
- task_destroy(m, task, 0);
+ task_destroy(m, task, 1);
}
return 0;
}
@@ -348,15 +348,6 @@ static void task_destroy(h2_mplx *m, h2_
ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, m->c,
"h2_task(%s): destroy", task->id);
- /* cleanup any buffered input */
- if (task->input.beam) {
- status = h2_beam_shutdown(task->input.beam, APR_NONBLOCK_READ);
- if (status != APR_SUCCESS){
- ap_log_cerror(APLOG_MARK, APLOG_WARNING, status, m->c, APLOGNO(03385)
- "h2_task(%s): input shutdown", task->id);
- }
- }
-
if (called_from_master) {
/* Process outstanding events before destruction */
h2_stream *stream = h2_ihash_get(m->streams, task->stream_id);
@@ -372,6 +363,12 @@ static void task_destroy(h2_mplx *m, h2_
m->tx_handles_reserved +=
h2_beam_get_files_beamed(task->output.beam);
h2_beam_on_produced(task->output.beam, NULL, NULL);
+ status = h2_beam_shutdown(task->output.beam, APR_NONBLOCK_READ, 1);
+ if (status != APR_SUCCESS){
+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, status, m->c,
+ APLOGNO(03385) "h2_task(%s): output shutdown "
+ "incomplete", task->id);
+ }
}
slave = task->c;
@@ -438,6 +435,8 @@ static void stream_done(h2_mplx *m, h2_s
h2_ihash_remove(m->streams, stream->id);
if (stream->input) {
m->tx_handles_reserved += h2_beam_get_files_beamed(stream->input);
+ h2_beam_on_consumed(stream->input, NULL, NULL);
+ h2_beam_mutex_set(stream->input, NULL, NULL, NULL);
}
h2_stream_cleanup(stream);
@@ -651,6 +650,7 @@ apr_status_t h2_mplx_stream_done(h2_mplx
"h2_mplx(%ld-%d): marking stream as done.",
m->id, stream->id);
stream_done(m, stream, stream->rst_error);
+ purge_streams(m);
leave_mutex(m, acquired);
}
return status;
@@ -766,6 +766,7 @@ apr_status_t h2_mplx_out_trywait(h2_mplx
status = APR_SUCCESS;
}
else {
+ purge_streams(m);
m->added_output = iowait;
status = apr_thread_cond_timedwait(m->added_output, m->lock, timeout);
if (APLOGctrace2(m->c)) {
@@ -1021,20 +1022,18 @@ static void task_done(h2_mplx *m, h2_tas
}
}
else {
- /* stream done, was it placed in hold? */
+ /* stream no longer active, was it placed in hold? */
stream = h2_ihash_get(m->shold, task->stream_id);
if (stream) {
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
"h2_mplx(%s): task_done, stream in hold",
task->id);
- stream->response = NULL; /* ref from task memory */
/* We cannot destroy the stream here since this is
* called from a worker thread and freeing memory pools
* is only safe in the only thread using it (and its
* parent pool / allocator) */
h2_ihash_remove(m->shold, stream->id);
h2_ihash_add(m->spurge, stream);
- task_destroy(m, task, 0);
}
else {
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
Modified: httpd/httpd/trunk/modules/http2/h2_stream.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_stream.c?rev=1747531&r1=1747530&r2=1747531&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_stream.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_stream.c Thu Jun 9 10:28:51 2016
@@ -213,12 +213,12 @@ void h2_stream_cleanup(h2_stream *stream
}
if (stream->input) {
apr_status_t status;
- status = h2_beam_shutdown(stream->input, APR_NONBLOCK_READ);
+ status = h2_beam_shutdown(stream->input, APR_NONBLOCK_READ, 1);
if (status == APR_EAGAIN) {
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c,
"h2_stream(%ld-%d): wait on input shutdown",
stream->session->id, stream->id);
- status = h2_beam_shutdown(stream->input, APR_BLOCK_READ);
+ status = h2_beam_shutdown(stream->input, APR_BLOCK_READ, 1);
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, stream->session->c,
"h2_stream(%ld-%d): input shutdown returned",
stream->session->id, stream->id);