diff options
author | Brian Pane <brianp@apache.org> | 2005-10-24 05:33:14 +0200 |
---|---|---|
committer | Brian Pane <brianp@apache.org> | 2005-10-24 05:33:14 +0200 |
commit | cb0e5db86f05e4851a7b85d24abece63297bbf7b (patch) | |
tree | 1f8841c80ce1634cc2636d44d313b458b0031af1 /modules/http | |
parent | Redesign of request cleanup and logging to use End-Of-Request bucket (diff) | |
download | apache2-cb0e5db86f05e4851a7b85d24abece63297bbf7b.tar.xz apache2-cb0e5db86f05e4851a7b85d24abece63297bbf7b.zip |
Async write completion for Event MPM
(backported from async-dev branch to 2.3 trunk)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@327945 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/http')
-rw-r--r-- | modules/http/http_core.c | 20 | ||||
-rw-r--r-- | modules/http/http_request.c | 51 |
2 files changed, 29 insertions, 42 deletions
diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 1a76bc941a..fad09ef190 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -122,26 +122,18 @@ static int ap_process_http_async_connection(conn_rec *c) /* process the request if it was read without error */ ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r); - if (r->status == HTTP_OK) - ap_process_request(r); + if (r->status == HTTP_OK) { + cs->state = CONN_STATE_HANDLER; + ap_process_async_request(r); + } if (ap_extended_status) ap_increment_counts(c->sbh, r); - if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted - || ap_graceful_stop_signalled()) { + if (cs->state != CONN_STATE_WRITE_COMPLETION) { + /* Something went wrong; close the connection */ cs->state = CONN_STATE_LINGER; } - else if (!c->data_in_input_filters) { - cs->state = CONN_STATE_CHECK_REQUEST_LINE_READABLE; - } - else { - /* else we are pipelining. Stay in READ_REQUEST_LINE state - * and stay in the loop - */ - cs->state = CONN_STATE_READ_REQUEST_LINE; - } - } else { /* ap_read_request failed - client may have closed */ cs->state = CONN_STATE_LINGER; diff --git a/modules/http/http_request.c b/modules/http/http_request.c index 07f37a070a..43abefc0eb 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -191,47 +191,23 @@ AP_DECLARE(void) ap_die(int type, request_rec *r) ap_send_error_response(r_1st_err, recursive_error); } -static void check_pipeline_flush(conn_rec *c) +static void check_pipeline(conn_rec *c) { - apr_bucket *e; - apr_bucket_brigade *bb; - - /* ### if would be nice if we could PEEK without a brigade. that would - ### allow us to defer creation of the brigade to when we actually - ### need to send a FLUSH. */ - bb = apr_brigade_create(c->pool, c->bucket_alloc); - - /* Flush the filter contents if: - * - * 1) the connection will be closed - * 2) there isn't a request ready to be read - */ /* ### is zero correct? that means "read one line" */ if (c->keepalive != AP_CONN_CLOSE) { + apr_bucket_brigade *bb = apr_brigade_create(c->pool, c->bucket_alloc); if (ap_get_brigade(c->input_filters, bb, AP_MODE_EATCRLF, APR_NONBLOCK_READ, 0) != APR_SUCCESS) { c->data_in_input_filters = 0; /* we got APR_EOF or an error */ } else { c->data_in_input_filters = 1; - return; /* don't flush */ } } - - e = apr_bucket_flush_create(c->bucket_alloc); - - /* We just send directly to the connection based filters. At - * this point, we know that we have seen all of the data - * (request finalization sent an EOS bucket, which empties all - * of the request filters). We just want to flush the buckets - * if something hasn't been sent to the network yet. - */ - APR_BRIGADE_INSERT_HEAD(bb, e); - ap_pass_brigade(c->output_filters, bb); } -void ap_process_request(request_rec *r) +void ap_process_async_request(request_rec *r) { int access_status; apr_bucket_brigade *bb; @@ -289,11 +265,30 @@ void ap_process_request(request_rec *r) */ c->cs->state = CONN_STATE_WRITE_COMPLETION; - check_pipeline_flush(c); + check_pipeline(c); if (ap_extended_status) ap_time_process_request(c->sbh, STOP_PREQUEST); } +void ap_process_request(request_rec *r) +{ + apr_bucket_brigade *bb; + apr_bucket *b; + conn_rec *c = r->connection; + + ap_process_async_request(r); + + if (!c->data_in_input_filters) { + bb = apr_brigade_create(c->pool, c->bucket_alloc); + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_HEAD(bb, b); + ap_pass_brigade(c->output_filters, bb); + } + if (ap_extended_status) { + ap_time_process_request(c->sbh, STOP_PREQUEST); + } +} + static apr_table_t *rename_original_env(apr_pool_t *p, apr_table_t *t) { const apr_array_header_t *env_arr = apr_table_elts(t); |