You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by br...@apache.org on 2006/01/02 14:43:45 UTC
svn commit: r365346 - in /httpd/httpd/branches/async-read-dev/server:
mpm/experimental/event/event.c protocol.c
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);
}