Return-Path: Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: (qmail 67506 invoked from network); 2 Jan 2006 13:44:10 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 2 Jan 2006 13:44:10 -0000 Received: (qmail 41495 invoked by uid 500); 2 Jan 2006 13:44:09 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 41451 invoked by uid 500); 2 Jan 2006 13:44:08 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 41432 invoked by uid 99); 2 Jan 2006 13:44:08 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Jan 2006 05:44:08 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Mon, 02 Jan 2006 05:44:07 -0800 Received: (qmail 67307 invoked by uid 65534); 2 Jan 2006 13:43:47 -0000 Message-ID: <20060102134347.67304.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r365346 - in /httpd/httpd/branches/async-read-dev/server: mpm/experimental/event/event.c protocol.c Date: Mon, 02 Jan 2006 13:43:45 -0000 To: cvs@httpd.apache.org From: brianp@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: brianp Date: Mon Jan 2 05:43:42 2006 New Revision: 365346 URL: http://svn.apache.org/viewcvs?rev=365346&view=rev Log: Initial implementation of asynchronous read completion for Event MPM Warning: SSL doesn't work, so these changes aren't ready to be merged to the trunk yet. Modified: httpd/httpd/branches/async-read-dev/server/mpm/experimental/event/event.c httpd/httpd/branches/async-read-dev/server/protocol.c Modified: httpd/httpd/branches/async-read-dev/server/mpm/experimental/event/event.c URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/async-read-dev/server/mpm/experimental/event/event.c?rev=365346&r1=365345&r2=365346&view=diff ============================================================================== --- httpd/httpd/branches/async-read-dev/server/mpm/experimental/event/event.c (original) +++ httpd/httpd/branches/async-read-dev/server/mpm/experimental/event/event.c Mon Jan 2 05:43:42 2006 @@ -683,7 +683,8 @@ ap_push_pool(worker_queue_info, p); return 1; } - else if (cs->state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) { + else if ((cs->state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) || + (cs->state == CONN_STATE_READ_REQUEST_LINE)) { apr_status_t rc; listener_poll_type *pt = (listener_poll_type *) cs->pfd.client_data; @@ -962,6 +963,7 @@ case CONN_STATE_CHECK_REQUEST_LINE_READABLE: cs->state = CONN_STATE_READ_REQUEST_LINE; break; + case CONN_STATE_READ_REQUEST_LINE: case CONN_STATE_WRITE_COMPLETION: break; default: Modified: httpd/httpd/branches/async-read-dev/server/protocol.c URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/async-read-dev/server/protocol.c?rev=365346&r1=365345&r2=365346&view=diff ============================================================================== --- httpd/httpd/branches/async-read-dev/server/protocol.c (original) +++ httpd/httpd/branches/async-read-dev/server/protocol.c Mon Jan 2 05:43:42 2006 @@ -476,6 +476,123 @@ return (int)len; } +static apr_status_t getline_nonblocking(char **s, apr_size_t n, + apr_size_t *read, request_rec *r, + apr_bucket_brigade *bb) +{ + apr_status_t rv; + apr_bucket *e; + apr_size_t bytes_handled = 0, current_alloc = 0; + char *pos, *last_char = *s; + int do_alloc = (*s == NULL), saw_eos = 0; + + // return ap_rgetline_core(s, n, read, r, 0, bb); + apr_brigade_cleanup(bb); + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_GETLINE, + APR_NONBLOCK_READ, 0); + if (rv != APR_SUCCESS) { + return rv; + } + + if (APR_BRIGADE_EMPTY(bb)) { + return APR_EAGAIN; + } + + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb); + e = APR_BUCKET_NEXT(e)) + { + const char *str; + apr_size_t len; + + /* If we see an EOS, don't bother doing anything more. */ + if (APR_BUCKET_IS_EOS(e)) { + saw_eos = 1; + break; + } + + rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + return rv; + } + + if (len == 0) { + /* no use attempting a zero-byte alloc (hurts when + * using --with-efence --enable-pool-debug) or + * doing any of the other logic either + */ + continue; + } + + /* Would this overrun our buffer? If so, we'll die. */ + if (n < bytes_handled + len) { + *read = bytes_handled; + if (*s) { + /* ensure this string is NUL terminated */ + if (bytes_handled > 0) { + (*s)[bytes_handled-1] = '\0'; + } + else { + (*s)[0] = '\0'; + } + } + return APR_ENOSPC; + } + + /* Do we have to handle the allocation ourselves? */ + if (do_alloc) { + /* We'll assume the common case where one bucket is enough. */ + if (!*s) { + current_alloc = len; + if (current_alloc < MIN_LINE_ALLOC) { + current_alloc = MIN_LINE_ALLOC; + } + *s = apr_palloc(r->pool, current_alloc); + } + else if (bytes_handled + len > current_alloc) { + /* Increase the buffer size */ + apr_size_t new_size = current_alloc * 2; + char *new_buffer; + + if (bytes_handled + len > new_size) { + new_size = (bytes_handled + len) * 2; + } + + new_buffer = apr_palloc(r->pool, new_size); + + /* Copy what we already had. */ + memcpy(new_buffer, *s, bytes_handled); + current_alloc = new_size; + *s = new_buffer; + } + } + + /* Just copy the rest of the data to the end of the old buffer. */ + pos = *s + bytes_handled; + memcpy(pos, str, len); + last_char = pos + len - 1; + + /* We've now processed that new data - update accordingly. */ + bytes_handled += len; + } + + if (bytes_handled == 0) { + return APR_EAGAIN; + } + + /* Now NUL-terminate the string at the end of the line; + * if the last-but-one character is a CR, terminate there */ + if (last_char > *s && last_char[-1] == APR_ASCII_CR) { + last_char--; + } + *last_char = '\0'; + bytes_handled = last_char - *s; + fprintf(stderr, "read line '%s'\n", *s); + + *read = bytes_handled; + return APR_SUCCESS; +} + /* parse_uri: break apart the uri * Side Effects: * - sets r->args to rest after '?' (or NULL if no '?') @@ -966,9 +1083,8 @@ } length_limit = r->server->limit_req_fieldsize; } - /* TODO: use a nonblocking call in place of ap_rgetline */ - rv = ap_rgetline(&line, length_limit + 2, - &line_length, r, 0, tmp_bb); + rv = getline_nonblocking(&line, length_limit + 2, + &line_length, r, tmp_bb); if (rv == APR_SUCCESS) { rv = process_request_line(r, line, 0); }