Skip to content

Commit

Permalink
* fixed idle connection handling for non-async MPMs, like worker.
Browse files Browse the repository at this point in the history
   With mpm_worker, idle conection could go into a busy loop waiting for
   new data to arrive.
  • Loading branch information
icing committed Sep 23, 2022
1 parent c62985b commit f7a2d61
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 7 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
* fixed idle connection handling for non-async MPMs, like worker.
With mpm_worker, idle conection could go into a busy loop waiting for
new data to arrive.

v2.0.6
--------------------------------------------------------------------------------
* fixed handling of connection `Timeout` setting to not apply when streams
Expand Down
8 changes: 6 additions & 2 deletions mod_http2/h2_mplx.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ void h2_mplx_c1_destroy(h2_mplx *m)
H2_MPLX_MSG(m, "start release"));
/* How to shut down a h2 connection:
* 0. abort and tell the workers that no more work will come from us */
m->aborted = 1;
m->shutdown = m->aborted = 1;

H2_MPLX_ENTER_ALWAYS(m);

Expand Down Expand Up @@ -967,6 +967,7 @@ static void workers_shutdown(void *baton, int graceful)
/* time to wakeup and assess what to do */
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
H2_MPLX_MSG(m, "workers shutdown, waking pollset"));
m->shutdown = 1;
if (!graceful) {
m->aborted = 1;
}
Expand Down Expand Up @@ -1125,7 +1126,10 @@ static apr_status_t mplx_pollset_poll(h2_mplx *m, apr_interval_time_t timeout,
H2_MPLX_LEAVE(m);
rv = apr_pollset_poll(m->pollset, timeout >= 0? timeout : -1, &nresults, &results);
H2_MPLX_ENTER_ALWAYS(m);
if (APR_STATUS_IS_EINTR(rv) && m->aborted) {
if (APR_STATUS_IS_EINTR(rv) && m->shutdown) {
if (!m->aborted) {
rv = APR_SUCCESS;
}
goto cleanup;
}
} while (APR_STATUS_IS_EINTR(rv));
Expand Down
3 changes: 2 additions & 1 deletion mod_http2/h2_mplx.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ struct h2_mplx {
struct h2_stream *stream0; /* HTTP/2's stream 0 */
server_rec *s; /* server for master conn */

int aborted;
int shutdown; /* we are shutting down */
int aborted; /* we need to get out of here asap */
int polling; /* is waiting/processing pollset events */
ap_conn_producer_t *producer; /* registered producer at h2_workers */

Expand Down
33 changes: 29 additions & 4 deletions mod_http2/h2_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -1864,10 +1864,35 @@ apr_status_t h2_session_process(h2_session *session, int async)
* connection handling when nothing really happened. */
h2_c1_read(session);
if (H2_SESSION_ST_IDLE == session->state) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
H2_SSSN_LOG(APLOGNO(10306), session,
"returning to mpm c1 monitoring"));
goto leaving;
if (async) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
H2_SSSN_LOG(APLOGNO(10306), session,
"returning to mpm c1 monitoring"));
goto leaving;
}
else {
/* Not an async mpm, we must continue waiting
* for client data to arrive until the configured
* server Timeout/KeepAliveTimeout happens */
apr_time_t timeout = (session->open_streams == 0)?
session->s->keep_alive_timeout :
session->s->timeout;
status = h2_mplx_c1_poll(session->mplx, timeout,
on_stream_input,
on_stream_output, session);
if (APR_STATUS_IS_TIMEUP(status)) {
if (session->open_streams == 0) {
h2_session_dispatch_event(session,
H2_SESSION_EV_CONN_TIMEOUT, status, NULL);
break;
}
}
else if (APR_SUCCESS != status) {
h2_session_dispatch_event(session,
H2_SESSION_EV_CONN_ERROR, status, NULL);
break;
}
}
}
}
else {
Expand Down

0 comments on commit f7a2d61

Please sign in to comment.