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 2022/03/21 08:19:29 UTC
svn commit: r1899102 - in /httpd/httpd/trunk/modules/http2: h2.h h2_c2.c h2_conn_ctx.c h2_conn_ctx.h h2_mplx.c h2_mplx.h
Author: icing
Date: Mon Mar 21 08:19:28 2022
New Revision: 1899102
URL: http://svn.apache.org/viewvc?rev=1899102&view=rev
Log:
*) mod_http2: use pollset only for main connection and wakeups
for events on streams. Provide streams in INPUT pipe when
needed and supported on the platform.
Modified:
httpd/httpd/trunk/modules/http2/h2.h
httpd/httpd/trunk/modules/http2/h2_c2.c
httpd/httpd/trunk/modules/http2/h2_conn_ctx.c
httpd/httpd/trunk/modules/http2/h2_conn_ctx.h
httpd/httpd/trunk/modules/http2/h2_mplx.c
httpd/httpd/trunk/modules/http2/h2_mplx.h
Modified: httpd/httpd/trunk/modules/http2/h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2.h?rev=1899102&r1=1899101&r2=1899102&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2.h (original)
+++ httpd/httpd/trunk/modules/http2/h2.h Mon Mar 21 08:19:28 2022
@@ -59,11 +59,10 @@ struct h2_stream;
* are used for many consecutive requests where
* pollsets stay unchanged much longer.
*/
-#define H2_NO_POLL_STREAMS 1
-#ifdef H2_NO_POLL_STREAMS
-#define H2_POLL_STREAMS 0
+#ifdef H2_NO_PIPES
+#define H2_USE_PIPES 0
#else
-#define H2_POLL_STREAMS (APR_FILES_AS_SOCKETS && APR_VERSION_AT_LEAST(1,6,0))
+#define H2_USE_PIPES (APR_FILES_AS_SOCKETS && APR_VERSION_AT_LEAST(1,6,0))
#endif
/**
Modified: httpd/httpd/trunk/modules/http2/h2_c2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_c2.c?rev=1899102&r1=1899101&r2=1899102&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_c2.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_c2.c Mon Mar 21 08:19:28 2022
@@ -225,12 +225,12 @@ static apr_status_t h2_c2_filter_in(ap_f
conn_ctx->id, conn_ctx->stream_id, block, (long)readbytes);
}
if (conn_ctx->beam_in) {
- if (conn_ctx->pipe_in_prod[H2_PIPE_OUT]) {
+ if (conn_ctx->pipe_in[H2_PIPE_OUT]) {
receive:
status = h2_beam_receive(conn_ctx->beam_in, f->c, fctx->bb, APR_NONBLOCK_READ,
conn_ctx->mplx->stream_max_mem);
if (APR_STATUS_IS_EAGAIN(status) && APR_BLOCK_READ == block) {
- status = h2_util_wait_on_pipe(conn_ctx->pipe_in_prod[H2_PIPE_OUT]);
+ status = h2_util_wait_on_pipe(conn_ctx->pipe_in[H2_PIPE_OUT]);
if (APR_SUCCESS == status) {
goto receive;
}
Modified: httpd/httpd/trunk/modules/http2/h2_conn_ctx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn_ctx.c?rev=1899102&r1=1899101&r2=1899102&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_conn_ctx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_conn_ctx.c Mon Mar 21 08:19:28 2022
@@ -58,11 +58,11 @@ h2_conn_ctx_t *h2_conn_ctx_create_for_c1
ctx->server = s;
ctx->protocol = apr_pstrdup(c1->pool, protocol);
- ctx->pfd_out_prod.desc_type = APR_POLL_SOCKET;
- ctx->pfd_out_prod.desc.s = ap_get_conn_socket(c1);
- apr_socket_opt_set(ctx->pfd_out_prod.desc.s, APR_SO_NONBLOCK, 1);
- ctx->pfd_out_prod.reqevents = APR_POLLIN | APR_POLLERR | APR_POLLHUP;
- ctx->pfd_out_prod.client_data = ctx;
+ ctx->pfd.desc_type = APR_POLL_SOCKET;
+ ctx->pfd.desc.s = ap_get_conn_socket(c1);
+ ctx->pfd.reqevents = APR_POLLIN | APR_POLLERR | APR_POLLHUP;
+ ctx->pfd.client_data = ctx;
+ apr_socket_opt_set(ctx->pfd.desc.s, APR_SO_NONBLOCK, 1);
return ctx;
}
@@ -107,14 +107,10 @@ void h2_conn_ctx_set_timeout(h2_conn_ctx
if (conn_ctx->beam_out) {
h2_beam_timeout_set(conn_ctx->beam_out, timeout);
}
- if (conn_ctx->pipe_out_prod[H2_PIPE_OUT]) {
- apr_file_pipe_timeout_set(conn_ctx->pipe_out_prod[H2_PIPE_OUT], timeout);
- }
-
if (conn_ctx->beam_in) {
h2_beam_timeout_set(conn_ctx->beam_in, timeout);
}
- if (conn_ctx->pipe_in_prod[H2_PIPE_OUT]) {
- apr_file_pipe_timeout_set(conn_ctx->pipe_in_prod[H2_PIPE_OUT], timeout);
+ if (conn_ctx->pipe_in[H2_PIPE_OUT]) {
+ apr_file_pipe_timeout_set(conn_ctx->pipe_in[H2_PIPE_OUT], timeout);
}
}
Modified: httpd/httpd/trunk/modules/http2/h2_conn_ctx.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn_ctx.h?rev=1899102&r1=1899101&r2=1899102&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_conn_ctx.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_conn_ctx.h Mon Mar 21 08:19:28 2022
@@ -50,10 +50,8 @@ struct h2_conn_ctx_t {
struct h2_bucket_beam *beam_out; /* c2: data out, created from req_pool */
struct h2_bucket_beam *beam_in; /* c2: data in or NULL, borrowed from request stream */
- apr_file_t *pipe_in_prod[2]; /* c2: input produced notification pipe */
- apr_file_t *pipe_out_prod[2]; /* c2: output produced notification pipe */
-
- apr_pollfd_t pfd_out_prod; /* c2: poll pipe_out_prod output */
+ apr_file_t *pipe_in[2]; /* c2: input produced notification pipe */
+ apr_pollfd_t pfd; /* c1: poll socket input, c2: NUL */
int has_final_response; /* final HTTP response passed on out */
apr_status_t last_err; /* APR_SUCCES or last error encountered in filters */
Modified: httpd/httpd/trunk/modules/http2/h2_mplx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.c?rev=1899102&r1=1899101&r2=1899102&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.c Mon Mar 21 08:19:28 2022
@@ -61,8 +61,6 @@ static apr_status_t s_mplx_be_happy(h2_m
static apr_status_t m_be_annoyed(h2_mplx *m);
static apr_status_t mplx_pollset_create(h2_mplx *m);
-static apr_status_t mplx_pollset_add(h2_mplx *m, h2_conn_ctx_t *conn_ctx);
-static apr_status_t mplx_pollset_remove(h2_mplx *m, h2_conn_ctx_t *conn_ctx);
static apr_status_t mplx_pollset_poll(h2_mplx *m, apr_interval_time_t timeout,
stream_ev_callback *on_stream_input,
stream_ev_callback *on_stream_output,
@@ -313,20 +311,19 @@ h2_mplx *h2_mplx_c1_create(h2_stream *st
"nghttp2: could not create pollset");
goto failure;
}
- m->streams_to_poll = apr_array_make(m->pool, 10, sizeof(h2_stream*));
m->streams_ev_in = apr_array_make(m->pool, 10, sizeof(h2_stream*));
m->streams_ev_out = apr_array_make(m->pool, 10, sizeof(h2_stream*));
m->streams_input_read = h2_iq_create(m->pool, 10);
+ m->streams_output_written = h2_iq_create(m->pool, 10);
status = apr_thread_mutex_create(&m->poll_lock, APR_THREAD_MUTEX_DEFAULT,
m->pool);
if (APR_SUCCESS != status) goto failure;
-#if !H2_POLL_STREAMS
- m->streams_output_written = h2_iq_create(m->pool, 10);
-#endif
conn_ctx = h2_conn_ctx_get(m->c1);
- mplx_pollset_add(m, conn_ctx);
+ if (conn_ctx->pfd.reqevents) {
+ apr_pollset_add(m->pollset, &conn_ctx->pfd);
+ }
m->scratch_r = apr_pcalloc(m->pool, sizeof(*m->scratch_r));
m->max_spare_transits = 3;
@@ -550,17 +547,9 @@ static void c1_purge_streams(h2_mplx *m)
if (stream->c2) {
conn_rec *c2 = stream->c2;
h2_conn_ctx_t *c2_ctx = h2_conn_ctx_get(c2);
- apr_status_t rv;
stream->c2 = NULL;
ap_assert(c2_ctx);
- rv = mplx_pollset_remove(m, c2_ctx);
- if (APR_SUCCESS != rv) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, rv, m->c1,
- "h2_mplx(%ld-%d): pollset_remove %d on purge",
- m->id, stream->id, c2_ctx->stream_id);
- }
-
h2_c2_destroy(c2);
if (c2_ctx->transit) {
c2_transit_recycle(m, c2_ctx->transit);
@@ -753,8 +742,8 @@ static void c2_beam_input_write_notify(v
h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
(void)beam;
- if (conn_ctx && conn_ctx->stream_id && conn_ctx->pipe_in_prod[H2_PIPE_IN]) {
- apr_file_putc(1, conn_ctx->pipe_in_prod[H2_PIPE_IN]);
+ if (conn_ctx && conn_ctx->stream_id && conn_ctx->pipe_in[H2_PIPE_IN]) {
+ apr_file_putc(1, conn_ctx->pipe_in[H2_PIPE_IN]);
}
}
@@ -777,17 +766,10 @@ static void c2_beam_output_write_notify(
h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
if (conn_ctx && conn_ctx->stream_id) {
- if (conn_ctx->pipe_out_prod[H2_PIPE_IN]) {
- apr_file_putc(1, conn_ctx->pipe_out_prod[H2_PIPE_IN]);
- }
-#if !H2_POLL_STREAMS
- else {
- apr_thread_mutex_lock(conn_ctx->mplx->poll_lock);
- h2_iq_append(conn_ctx->mplx->streams_output_written, conn_ctx->stream_id);
- apr_pollset_wakeup(conn_ctx->mplx->pollset);
- apr_thread_mutex_unlock(conn_ctx->mplx->poll_lock);
- }
-#endif
+ apr_thread_mutex_lock(conn_ctx->mplx->poll_lock);
+ h2_iq_append(conn_ctx->mplx->streams_output_written, conn_ctx->stream_id);
+ apr_pollset_wakeup(conn_ctx->mplx->pollset);
+ apr_thread_mutex_unlock(conn_ctx->mplx->poll_lock);
}
}
@@ -817,33 +799,19 @@ static apr_status_t c2_setup_io(h2_mplx
h2_beam_on_consumed(stream->input, c1_input_consumed, stream);
}
-#if H2_POLL_STREAMS
- if (!conn_ctx->pipe_out_prod[H2_PIPE_OUT]) {
- action = "create output pipe";
- rv = apr_file_pipe_create_pools(&conn_ctx->pipe_out_prod[H2_PIPE_OUT],
- &conn_ctx->pipe_out_prod[H2_PIPE_IN],
- APR_FULL_NONBLOCK,
- c2->pool, c2->pool);
- if (APR_SUCCESS != rv) goto cleanup;
- }
- conn_ctx->pfd_out_prod.desc_type = APR_POLL_FILE;
- conn_ctx->pfd_out_prod.desc.f = conn_ctx->pipe_out_prod[H2_PIPE_OUT];
- conn_ctx->pfd_out_prod.reqevents = APR_POLLIN | APR_POLLERR | APR_POLLHUP;
- conn_ctx->pfd_out_prod.client_data = conn_ctx;
-
+#if H2_USE_PIPES
if (stream->input) {
- if (!conn_ctx->pipe_in_prod[H2_PIPE_OUT]) {
+ if (!conn_ctx->pipe_in[H2_PIPE_OUT]) {
action = "create input write pipe";
- rv = apr_file_pipe_create_pools(&conn_ctx->pipe_in_prod[H2_PIPE_OUT],
- &conn_ctx->pipe_in_prod[H2_PIPE_IN],
+ rv = apr_file_pipe_create_pools(&conn_ctx->pipe_in[H2_PIPE_OUT],
+ &conn_ctx->pipe_in[H2_PIPE_IN],
APR_READ_BLOCK,
c2->pool, c2->pool);
if (APR_SUCCESS != rv) goto cleanup;
}
}
#else
- memset(&conn_ctx->pfd_out_prod, 0, sizeof(conn_ctx->pfd_out_prod));
- memset(&conn_ctx->pipe_in_prod, 0, sizeof(conn_ctx->pipe_in_prod));
+ memset(&conn_ctx->pipe_in, 0, sizeof(conn_ctx->pipe_in));
#endif
cleanup:
@@ -894,8 +862,6 @@ static conn_rec *s_next_c2(h2_mplx *m)
stream->c2 = c2;
++m->processing_count;
- APR_ARRAY_PUSH(m->streams_to_poll, h2_stream *) = stream;
- apr_pollset_wakeup(m->pollset);
cleanup:
if (APR_SUCCESS != rv && c2) {
@@ -1122,33 +1088,11 @@ apr_status_t h2_mplx_c1_client_rst(h2_mp
static apr_status_t mplx_pollset_create(h2_mplx *m)
{
- int max_pdfs;
-
- /* stream0 output, pdf_out+pfd_in_consume per active streams */
- max_pdfs = 1 + 2 * H2MIN(m->processing_max, m->max_streams);
- return apr_pollset_create(&m->pollset, max_pdfs, m->pool,
+ /* stream0 output only */
+ return apr_pollset_create(&m->pollset, 1, m->pool,
APR_POLLSET_WAKEABLE);
}
-static apr_status_t mplx_pollset_add(h2_mplx *m, h2_conn_ctx_t *conn_ctx)
-{
- if (conn_ctx->pfd_out_prod.reqevents) {
- return apr_pollset_add(m->pollset, &conn_ctx->pfd_out_prod);
- }
- return APR_SUCCESS;
-}
-
-static apr_status_t mplx_pollset_remove(h2_mplx *m, h2_conn_ctx_t *conn_ctx)
-{
- apr_status_t rv = APR_SUCCESS;
-
- if (conn_ctx->pfd_out_prod.reqevents) {
- rv = apr_pollset_remove(m->pollset, &conn_ctx->pfd_out_prod);
- conn_ctx->pfd_out_prod.reqevents = 0;
- }
- return rv;
-}
-
static apr_status_t mplx_pollset_poll(h2_mplx *m, apr_interval_time_t timeout,
stream_ev_callback *on_stream_input,
stream_ev_callback *on_stream_output,
@@ -1173,31 +1117,15 @@ static apr_status_t mplx_pollset_poll(h2
do {
/* add streams we started processing in the meantime */
- if (m->streams_to_poll->nelts) {
- for (i = 0; i < m->streams_to_poll->nelts; ++i) {
- stream = APR_ARRAY_IDX(m->streams_to_poll, i, h2_stream*);
- if (stream && stream->c2 && (conn_ctx = h2_conn_ctx_get(stream->c2))) {
- mplx_pollset_add(m, conn_ctx);
- }
- }
- apr_array_clear(m->streams_to_poll);
- }
-
apr_thread_mutex_lock(m->poll_lock);
- if (!h2_iq_empty(m->streams_input_read)) {
+ if (!h2_iq_empty(m->streams_input_read)
+ || !h2_iq_empty(m->streams_output_written)) {
while ((i = h2_iq_shift(m->streams_input_read))) {
stream = h2_ihash_get(m->streams, i);
if (stream) {
APR_ARRAY_PUSH(m->streams_ev_in, h2_stream*) = stream;
}
}
- nresults = 0;
- rv = APR_SUCCESS;
- apr_thread_mutex_unlock(m->poll_lock);
- break;
- }
-#if !H2_POLL_STREAMS
- if (!h2_iq_empty(m->streams_output_written)) {
while ((i = h2_iq_shift(m->streams_output_written))) {
stream = h2_ihash_get(m->streams, i);
if (stream) {
@@ -1209,7 +1137,6 @@ static apr_status_t mplx_pollset_poll(h2
apr_thread_mutex_unlock(m->poll_lock);
break;
}
-#endif
apr_thread_mutex_unlock(m->poll_lock);
H2_MPLX_LEAVE(m);
@@ -1235,68 +1162,13 @@ static apr_status_t mplx_pollset_poll(h2
pfd = &results[i];
conn_ctx = pfd->client_data;
- ap_assert(conn_ctx);
+ AP_DEBUG_ASSERT(conn_ctx);
if (conn_ctx->stream_id == 0) {
if (on_stream_input) {
APR_ARRAY_PUSH(m->streams_ev_in, h2_stream*) = m->stream0;
}
continue;
}
-
- h2_util_drain_pipe(pfd->desc.f);
- stream = h2_ihash_get(m->streams, conn_ctx->stream_id);
- if (!stream) {
- stream = h2_ihash_get(m->shold, conn_ctx->stream_id);
- if (stream) {
- /* This is normal and means that stream processing on c1 has
- * already finished to CLEANUP and c2 is not done yet */
- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, m->c1,
- "h2_mplx(%ld-%d): stream already in hold for poll event %hx",
- m->id, conn_ctx->stream_id, pfd->rtnevents);
- }
- else {
- h2_stream *sp = NULL;
- int j;
-
- for (j = 0; j < m->spurge->nelts; ++j) {
- sp = APR_ARRAY_IDX(m->spurge, j, h2_stream*);
- if (sp->id == conn_ctx->stream_id) {
- stream = sp;
- break;
- }
- }
-
- if (stream) {
- /* This is normal and means that stream processing on c1 has
- * already finished to CLEANUP and c2 is not done yet */
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, m->c1, APLOGNO(10311)
- "h2_mplx(%ld-%d): stream already in purge for poll event %hx",
- m->id, conn_ctx->stream_id, pfd->rtnevents);
- }
- else {
- /* This should not happen. When a stream has been purged,
- * it MUST no longer appear in the pollset. Puring is done
- * outside the poll result processing. */
- ap_log_cerror(APLOG_MARK, APLOG_WARNING, rv, m->c1, APLOGNO(10312)
- "h2_mplx(%ld-%d): stream no longer known for poll event %hx"
- ", m->streams=%d, conn_ctx=%lx, fd=%lx",
- m->id, conn_ctx->stream_id, pfd->rtnevents,
- (int)h2_ihash_count(m->streams),
- (long)conn_ctx, (long)pfd->desc.f);
- h2_ihash_iter(m->streams, m_report_stream_iter, m);
- }
- }
- continue;
- }
-
- if (conn_ctx->pfd_out_prod.desc.f == pfd->desc.f) {
- /* output is available */
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c1,
- "[%s-%d] poll output event %hx",
- conn_ctx->id, conn_ctx->stream_id,
- pfd->rtnevents);
- APR_ARRAY_PUSH(m->streams_ev_out, h2_stream*) = stream;
- }
}
if (on_stream_input && m->streams_ev_in->nelts) {
Modified: httpd/httpd/trunk/modules/http2/h2_mplx.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.h?rev=1899102&r1=1899101&r2=1899102&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.h Mon Mar 21 08:19:28 2022
@@ -86,7 +86,6 @@ struct h2_mplx {
struct apr_thread_cond_t *join_wait;
apr_pollset_t *pollset; /* pollset for c1/c2 IO events */
- apr_array_header_t *streams_to_poll; /* streams to add to the pollset */
apr_array_header_t *streams_ev_in;
apr_array_header_t *streams_ev_out;