Changes with Apache 2.4.7
+ *) core, mod_ssl: Enable the ability for a module to reverse the sense of
+ a poll event from a read to a write or vice versa. This is a step on
+ the way to allow mod_ssl taking full advantage of the event MPM.
+ [Graham Leggett]
+
*) Makefile.win: Install proper pcre DLL file during debug build install.
PR 55235. [Ben Reser <ben reser org>]
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * core, mod_ssl: Lift the restriction that prevents mod_ssl taking
- full advantage of the event MPM. Enable the ability for a module
- to reverse the sense of a poll event from a read to a write or vice
- versa.
- trunk patches: http://svn.apache.org/r1470679
- http://svn.apache.org/r1477094
- 2.4.x patch: http://people.apache.org/~minfrin/httpd-event-ssl.patch
- +1: minfrin, jim, sf
- sf: These docs/CHANGES commits should be included, too:
- http://svn.apache.org/r1514214
- http://svn.apache.org/r1514617
-
* configure: '--enable-maintainer-mode' should also auto-enable mod_bucketeer
trunk: http://svn.apache.org/viewvc?view=revision&revision=1503680
2.4.x patch: trunk patch works
status page of <module>mod_status</module> shows how many connections are
in the mentioned states.</p>
- <p>The improved connection handling does not yet work for certain
- connection filters, in particular SSL. For SSL connections, this MPM will
- fall back to the behaviour of the <module>worker</module> MPM and
- reserve one worker thread per connection.</p>
+ <p>The improved connection handling may not work for certain connection
+ filters that have declared themselves as incompatible with event. In these
+ cases, this MPM will fall back to the behaviour of the
+ <module>worker</module> MPM and reserve one worker thread per connection.
+ All modules shipped with the server are compatible with the event MPM.</p>
+
+ <p>A similar restriction is currently present for requests involving an
+ output filter that needs to read and/or modify the whole response body,
+ like for example mod_ssl, mod_deflate, or mod_include. If the
+ connection to the client blocks while the filter is processing the
+ data, and the amount of data produced by the filter is too big to be
+ buffered in memory, the thread used for the request is not freed while
+ httpd waits until the pending data is sent to the client.</p>
<p>The MPM assumes that the underlying <code>apr_pollset</code>
implementation is reasonably threadsafe. This enables the MPM to
<usage>
<p>The event MPM handles some connections in an asynchronous way, where
request worker threads are only allocated for short periods of time as
- needed, and other (mostly SSL) connections with one request worker thread
- reserved per connection. This can lead to situations where all workers are
- tied up and no worker thread is available to handle new work on established
- async connections.</p>
+ needed, and other connections with one request worker thread reserved per
+ connection. This can lead to situations where all workers are tied up and
+ no worker thread is available to handle new work on established async
+ connections.</p>
<p>To mitigate this problem, the event MPM does two things: Firstly, it
limits the number of connections accepted per process, depending on the
* 20120211.22 (2.4.5-dev) No longer prevent usage of strtoul()
* 20120211.23 (2.4.5-dev) Add ap_proxy_clear_connection()
* 20120211.24 (2.4.7-dev) add open_htaccess hook.
+ * 20120211.25 (2.4.7-dev) Add conn_sense_e
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20120211
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 24 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 25 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
CONN_STATE_LINGER_SHORT /* MPM has started lingering close with short timeout */
} conn_state_e;
+typedef enum {
+ CONN_SENSE_DEFAULT,
+ CONN_SENSE_WANT_READ, /* next event must be read */
+ CONN_SENSE_WANT_WRITE /* next event must be write */
+} conn_sense_e;
+
/**
* @brief A structure to contain connection state information
*/
struct conn_state_t {
/** Current state of the connection */
conn_state_e state;
+ /** Whether to read instead of write, or write instead of read */
+ conn_sense_e sense;
};
/* Per-vhost config... */
*/
outctx->rc = APR_EAGAIN;
}
+ else if (ssl_err == SSL_ERROR_WANT_READ) {
+ /*
+ * If OpenSSL wants to read during write, and we were
+ * nonblocking, set the sense explicitly to read and
+ * report as an EAGAIN.
+ *
+ * (This is usually the case when the client forces an SSL
+ * renegotiation which is handled implicitly by OpenSSL.)
+ */
+ outctx->c->cs->sense = CONN_SENSE_WANT_READ;
+ outctx->rc = APR_EAGAIN;
+ }
else if (ssl_err == SSL_ERROR_SYSCALL) {
ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, APLOGNO(01993)
"SSL output filter write failed.");
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;
+ /* write is non blocking for the benefit of async mpm */
+ if (c->cs) {
+ BIO_set_nbio(filter_ctx->pbioWrite, 1);
+ }
ssl_io_input_add_filter(filter_ctx, c, r, ssl);
apr_atomic_inc32(&lingering_count);
apr_thread_mutex_lock(timeout_mutex);
TO_QUEUE_APPEND(*q, cs);
- cs->pfd.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR;
+ cs->pfd.reqevents = (
+ cs->pub.sense == CONN_SENSE_WANT_WRITE ? APR_POLLOUT :
+ APR_POLLIN) | APR_POLLHUP | APR_POLLERR;
+ cs->pub.sense = CONN_SENSE_DEFAULT;
rv = apr_pollset_add(event_pollset, &cs->pfd);
apr_thread_mutex_unlock(timeout_mutex);
if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) {
*/
cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
+ cs->pub.sense = CONN_SENSE_DEFAULT;
}
else {
c = cs->c;
}
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.
+ /* Since we have an input filter which 'clogs' the input stream,
+ * like mod_ssl used to, lets just do the normal read from input
+ * filters, like the Worker MPM does. Filters that need to write
+ * where they would otherwise read, or read where they would
+ * otherwise write, should set the sense appropriately.
*/
apr_atomic_inc32(&clogged_count);
ap_run_process_connection(c);
cs->expiration_time = ap_server_conf->timeout + apr_time_now();
apr_thread_mutex_lock(timeout_mutex);
TO_QUEUE_APPEND(write_completion_q, cs);
- cs->pfd.reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR;
+ cs->pfd.reqevents = (
+ cs->pub.sense == CONN_SENSE_WANT_READ ? APR_POLLIN :
+ APR_POLLOUT) | APR_POLLHUP | APR_POLLERR;
+ cs->pub.sense = CONN_SENSE_DEFAULT;
rc = apr_pollset_add(event_pollset, &cs->pfd);
apr_thread_mutex_unlock(timeout_mutex);
return;