Re: [PATCH] 'clogging' input filters and the event MPM
+1 (concept) On Jun 10, 2007, at 9:13 PM, Paul Querna wrote: Attached is a patch that should let people run mod_ssl under the Event MPM. Previously, the event mpm would put a socket into its event thread to wait for input, but due to issues with how mod_ssl might be buffering data (or the entire request) in it, this would cause SSL'ized requests to stall and fail with the event mpm. The attach patch adds a new field, clogging_input_filters, to the conn_rec. When this field is true, the event mpm will run a connection just like the worker mpm is -- that is a single thread will run the entire connection, including keepalives. Thoughts on committing this to trunk? Thanks, -Paul Index: server/mpm/experimental/event/event.c === --- server/mpm/experimental/event/event.c (revision 545614) +++ server/mpm/experimental/event/event.c (working copy) @@ -620,6 +620,16 @@ pt = cs-pfd.client_data; } +if (c-clogging_input_filters !c-aborted) { +/* Since we have an input filter which 'cloggs' the input stream, + * like mod_ssl, lets just do the normal read from input filters, + * like the Worker MPM does. + */ +ap_run_process_connection(c); +ap_lingering_close(c); +return 0; +} + read_request: if (cs-state == CONN_STATE_READ_REQUEST_LINE) { if (!c-aborted) { Index: server/core.c === --- server/core.c (revision 545614) +++ server/core.c (working copy) @@ -3803,6 +3803,7 @@ c-cs-c = c; c-cs-p = ptrans; c-cs-bucket_alloc = alloc; +c-clogging_input_filters = 0; return c; } Index: modules/http/http_core.c === --- modules/http/http_core.c(revision 545614) +++ modules/http/http_core.c(working copy) @@ -119,11 +119,17 @@ return DEFAULT_HTTP_PORT; } +static int ap_process_http_connection(conn_rec *c); + static int ap_process_http_async_connection(conn_rec *c) { request_rec *r; conn_state_t *cs = c-cs; +if (c-clogging_input_filters) { +return ap_process_http_connection(c); +} + AP_DEBUG_ASSERT(cs-state == CONN_STATE_READ_REQUEST_LINE); while (cs-state == CONN_STATE_READ_REQUEST_LINE) { Index: modules/ssl/ssl_engine_io.c === --- modules/ssl/ssl_engine_io.c (revision 545614) +++ modules/ssl/ssl_engine_io.c (working copy) @@ -1665,6 +1665,9 @@ filter_ctx-pbioWrite = BIO_new(bio_filter_out_method); filter_ctx-pbioWrite-ptr = (void *)bio_filter_out_ctx_new (filter_ctx, c); +/* We insert a clogging input filter. Let the core know. */ +c-clogging_input_filters = 1; + ssl_io_input_add_filter(filter_ctx, c, ssl); SSL_set_bio(ssl, filter_ctx-pbioRead, filter_ctx-pbioWrite); Index: include/httpd.h === --- include/httpd.h (revision 545614) +++ include/httpd.h (working copy) @@ -1081,6 +1081,11 @@ int data_in_input_filters; /** Is there data pending in the output filters? */ int data_in_output_filters; + +/** Are there any filters that clogg/buffer the input stream, breaking + * the event mpm. + */ +int clogging_input_filters; }; /**
[PATCH] 'clogging' input filters and the event MPM
Attached is a patch that should let people run mod_ssl under the Event MPM. Previously, the event mpm would put a socket into its event thread to wait for input, but due to issues with how mod_ssl might be buffering data (or the entire request) in it, this would cause SSL'ized requests to stall and fail with the event mpm. The attach patch adds a new field, clogging_input_filters, to the conn_rec. When this field is true, the event mpm will run a connection just like the worker mpm is -- that is a single thread will run the entire connection, including keepalives. Thoughts on committing this to trunk? Thanks, -Paul Index: server/mpm/experimental/event/event.c === --- server/mpm/experimental/event/event.c (revision 545614) +++ server/mpm/experimental/event/event.c (working copy) @@ -620,6 +620,16 @@ pt = cs-pfd.client_data; } +if (c-clogging_input_filters !c-aborted) { +/* Since we have an input filter which 'cloggs' the input stream, + * like mod_ssl, lets just do the normal read from input filters, + * like the Worker MPM does. + */ +ap_run_process_connection(c); +ap_lingering_close(c); +return 0; +} + read_request: if (cs-state == CONN_STATE_READ_REQUEST_LINE) { if (!c-aborted) { Index: server/core.c === --- server/core.c (revision 545614) +++ server/core.c (working copy) @@ -3803,6 +3803,7 @@ c-cs-c = c; c-cs-p = ptrans; c-cs-bucket_alloc = alloc; +c-clogging_input_filters = 0; return c; } Index: modules/http/http_core.c === --- modules/http/http_core.c(revision 545614) +++ modules/http/http_core.c(working copy) @@ -119,11 +119,17 @@ return DEFAULT_HTTP_PORT; } +static int ap_process_http_connection(conn_rec *c); + static int ap_process_http_async_connection(conn_rec *c) { request_rec *r; conn_state_t *cs = c-cs; +if (c-clogging_input_filters) { +return ap_process_http_connection(c); +} + AP_DEBUG_ASSERT(cs-state == CONN_STATE_READ_REQUEST_LINE); while (cs-state == CONN_STATE_READ_REQUEST_LINE) { Index: modules/ssl/ssl_engine_io.c === --- modules/ssl/ssl_engine_io.c (revision 545614) +++ modules/ssl/ssl_engine_io.c (working copy) @@ -1665,6 +1665,9 @@ filter_ctx-pbioWrite = BIO_new(bio_filter_out_method); filter_ctx-pbioWrite-ptr = (void *)bio_filter_out_ctx_new(filter_ctx, c); +/* We insert a clogging input filter. Let the core know. */ +c-clogging_input_filters = 1; + ssl_io_input_add_filter(filter_ctx, c, ssl); SSL_set_bio(ssl, filter_ctx-pbioRead, filter_ctx-pbioWrite); Index: include/httpd.h === --- include/httpd.h (revision 545614) +++ include/httpd.h (working copy) @@ -1081,6 +1081,11 @@ int data_in_input_filters; /** Is there data pending in the output filters? */ int data_in_output_filters; + +/** Are there any filters that clogg/buffer the input stream, breaking + * the event mpm. + */ +int clogging_input_filters; }; /**