From: Stefan Eissing Date: Thu, 28 Apr 2016 08:46:18 +0000 (+0000) Subject: mod_http2: more sparse scorebaord updates with overall stats, keeping last request... X-Git-Tag: 2.5.0-alpha~1691 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f9a544866c96296a5c633f0205557e63b377572;p=apache mod_http2: more sparse scorebaord updates with overall stats, keeping last request info visible longer git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1741392 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 0e320b2fd5..2d0fefcba7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_http2: scoreboard updates that summarize the h2 session (and replace + the last request information) will only happen when the session is idle or + in shutdown/done phase. [Stefan Eissing] + *) mod_http2: bucket beams now have safe mutex remove. Used for streams where the task worker has finished and all processing happens in the same thread again. [Stefan Eissing] diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c index ca94920298..dff0d7986a 100644 --- a/modules/http2/h2_session.c +++ b/modules/http2/h2_session.c @@ -1760,12 +1760,51 @@ static int is_accepting_streams(h2_session *session) } } +static void update_child_status(h2_session *session, int status, const char *msg) +{ + /* Assume that we also change code/msg when something really happened and + * avoid updating the scoreboard in between */ + if (session->last_status_code != status + || session->last_status_msg != msg) { + apr_snprintf(session->status, sizeof(session->status), + "%s, streams: %d/%d/%d/%d/%d (open/recv/resp/push/rst)", + msg? msg : "-", + (int)h2_ihash_count(session->streams), + (int)session->remote.emitted_count, + (int)session->responses_submitted, + (int)session->pushes_submitted, + (int)session->pushes_reset + session->streams_reset); + ap_update_child_status_descr(session->c->sbh, status, session->status); + } +} + static void transit(h2_session *session, const char *action, h2_session_state nstate) { - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03078) - "h2_session(%ld): transit [%s] -- %s --> [%s]", session->id, - state_name(session->state), action, state_name(nstate)); - session->state = nstate; + if (session->state != nstate) { + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03078) + "h2_session(%ld): transit [%s] -- %s --> [%s]", session->id, + state_name(session->state), action, state_name(nstate)); + session->state = nstate; + switch (session->state) { + case H2_SESSION_ST_IDLE: + update_child_status(session, (h2_ihash_empty(session->streams)? + SERVER_BUSY_KEEPALIVE + : SERVER_BUSY_READ), "idle"); + break; + case H2_SESSION_ST_REMOTE_SHUTDOWN: + update_child_status(session, SERVER_CLOSING, "remote goaway"); + break; + case H2_SESSION_ST_LOCAL_SHUTDOWN: + update_child_status(session, SERVER_CLOSING, "local goaway"); + break; + case H2_SESSION_ST_DONE: + update_child_status(session, SERVER_CLOSING, "done"); + break; + default: + /* nop */ + break; + } + } } static void h2_session_ev_init(h2_session *session, int arg, const char *msg) @@ -1774,7 +1813,6 @@ static void h2_session_ev_init(h2_session *session, int arg, const char *msg) case H2_SESSION_ST_INIT: transit(session, "init", H2_SESSION_ST_BUSY); break; - default: /* nop */ break; @@ -2039,29 +2077,11 @@ static void dispatch_event(h2_session *session, h2_session_event_t ev, static const int MAX_WAIT_MICROS = 200 * 1000; -static void update_child_status(h2_session *session, int status, const char *msg) -{ - /* Assume that we also change code/msg when something really happened and - * avoid updating the scoreboard in between */ - if (session->last_status_code != status - || session->last_status_msg != msg) { - apr_snprintf(session->status, sizeof(session->status), - "%s, streams: %d/%d/%d/%d/%d (open/recv/resp/push/rst)", - msg? msg : "-", - (int)h2_ihash_count(session->streams), - (int)session->remote.emitted_count, - (int)session->responses_submitted, - (int)session->pushes_submitted, - (int)session->pushes_reset + session->streams_reset); - ap_update_child_status_descr(session->c->sbh, status, session->status); - } -} - apr_status_t h2_session_process(h2_session *session, int async) { apr_status_t status = APR_SUCCESS; conn_rec *c = session->c; - int rv, have_written, have_read, mpm_state, no_streams; + int rv, have_written, have_read, mpm_state; ap_log_cerror( APLOG_MARK, APLOG_TRACE1, status, c, "h2_session(%ld): process start, async=%d", session->id, async); @@ -2104,12 +2124,10 @@ apr_status_t h2_session_process(h2_session *session, int async) break; case H2_SESSION_ST_IDLE: - no_streams = h2_ihash_empty(session->streams); - update_child_status(session, (no_streams? SERVER_BUSY_KEEPALIVE - : SERVER_BUSY_READ), "idle"); /* make certain, the client receives everything before we idle */ if (!session->keep_sync_until - && async && no_streams && !session->r && session->remote.emitted_count) { + && async && h2_ihash_empty(session->streams) + && !session->r && session->remote.emitted_count) { ap_log_cerror( APLOG_MARK, APLOG_TRACE1, status, c, "h2_session(%ld): async idle, nonblock read", session->id); /* We do not return to the async mpm immediately, since under @@ -2192,7 +2210,6 @@ apr_status_t h2_session_process(h2_session *session, int async) status = h2_session_read(session, 0); if (status == APR_SUCCESS) { have_read = 1; - update_child_status(session, SERVER_BUSY_READ, "busy"); dispatch_event(session, H2_SESSION_EV_DATA_READ, 0, NULL); } else if (status == APR_EAGAIN) { @@ -2260,7 +2277,6 @@ apr_status_t h2_session_process(h2_session *session, int async) if (h2_conn_io_flush(&session->io) != APR_SUCCESS) { dispatch_event(session, H2_SESSION_EV_CONN_ERROR, 0, NULL); } - update_child_status(session, SERVER_BUSY_READ, "wait"); } else if ((apr_time_now() - session->start_wait) >= session->s->timeout) { /* waited long enough */ @@ -2300,7 +2316,6 @@ apr_status_t h2_session_process(h2_session *session, int async) break; case H2_SESSION_ST_DONE: - update_child_status(session, SERVER_CLOSING, "done"); status = APR_EOF; goto out;