From: Stefan Eissing Date: Tue, 17 Nov 2015 14:51:31 +0000 (+0000) Subject: early release of h2_mplx on session end X-Git-Tag: 2.5.0-alpha~2639 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99a1c3ab3b3c8893d414b97bca8606fecd782d84;p=thirdparty%2Fapache%2Fhttpd.git early release of h2_mplx on session end git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1714802 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c index 3a0415f3ff8..5a385bf19d3 100644 --- a/modules/http2/h2_session.c +++ b/modules/http2/h2_session.c @@ -662,9 +662,20 @@ h2_session *h2_session_rcreate(request_rec *r, h2_config *config, return h2_session_create_int(r->connection, r, config, workers); } -void h2_session_cleanup(h2_session *session) +static void h2_session_cleanup(h2_session *session) { AP_DEBUG_ASSERT(session); + /* This is an early cleanup of the session that may + * discard what is no longer necessary for *new* streams + * and general HTTP/2 processing. + * At this point, all frames are in transit or somehwere in + * our buffers or passed down output filters. + * h2 streams might still being written out. + */ + if (session->mplx) { + h2_mplx_release_and_join(session->mplx, session->iowait); + session->mplx = NULL; + } if (session->ngh2) { nghttp2_session_del(session->ngh2); session->ngh2 = NULL; @@ -673,10 +684,6 @@ void h2_session_cleanup(h2_session *session) apr_pool_destroy(session->spare); session->spare = NULL; } - if (session->mplx) { - h2_mplx_release_and_join(session->mplx, session->iowait); - session->mplx = NULL; - } } void h2_session_destroy(h2_session *session) @@ -1194,11 +1201,18 @@ apr_status_t h2_session_stream_destroy(h2_session *session, h2_stream *stream) { apr_pool_t *pool = h2_stream_detach_pool(stream); - h2_mplx_stream_done(session->mplx, stream->id, stream->rst_error); - if (session->last_stream == stream) { - session->last_stream = NULL; + /* this may be called while the session has already freed + * some internal structures. */ + if (session->mplx) { + h2_mplx_stream_done(session->mplx, stream->id, stream->rst_error); + if (session->last_stream == stream) { + session->last_stream = NULL; + } + } + + if (session->streams) { + h2_stream_set_remove(session->streams, stream->id); } - h2_stream_set_remove(session->streams, stream->id); h2_stream_destroy(stream); if (pool) { diff --git a/modules/http2/h2_session.h b/modules/http2/h2_session.h index 052b0d7e388..90052fc9e7f 100644 --- a/modules/http2/h2_session.h +++ b/modules/http2/h2_session.h @@ -122,14 +122,6 @@ apr_status_t h2_session_process(h2_session *session); */ void h2_session_destroy(h2_session *session); -/** - * Cleanup session data while winding down. No new streams - * may be created afterwards, but existing stream can still be - * looked up. - * Called automatically on destroy. - */ -void h2_session_cleanup(h2_session *session); - /** * Cleanup the session and all objects it still contains. This will not * destroy h2_task instances that have not finished yet. diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c index ec55ceb698e..fd3ef358451 100644 --- a/modules/http2/h2_stream.c +++ b/modules/http2/h2_stream.c @@ -305,7 +305,7 @@ static apr_status_t h2_stream_input_flush(h2_stream *stream) if (status != APR_SUCCESS) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, stream->session->mplx->c, "h2_stream(%ld-%d): flushing input data", - stream->session->mplx->id, stream->id); + stream->session->id, stream->id); } } return status;