changeset 313:98f1a8028067

nginx-0.0.3-2004-04-13-19:08:48 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 13 Apr 2004 15:08:48 +0000
parents f5431a4bbc7d
children d71c87d11b16
files auto/cc src/event/modules/ngx_epoll_module.c src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_poll_module.c src/event/ngx_event_posted.c src/http/modules/proxy/ngx_http_proxy_handler.c src/http/modules/proxy/ngx_http_proxy_upstream.c src/http/ngx_http_headers.c src/http/ngx_http_request.c src/http/ngx_http_request.h
diffstat 10 files changed, 167 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/auto/cc
+++ b/auto/cc
@@ -2,7 +2,7 @@
 case $CC in
 
     *gcc*)
-         # gcc 2.7.2.3, 2.95.4, 3.3.2, 3.4
+         # gcc 2.7.2.3, 2.8.1, 2.95.4, 3.3.2, 3.3.3, 3.4
 
          # optimization
          #CFLAGS="$CFLAGS -O2 -fomit-frame-pointer"
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -300,6 +300,7 @@ static int ngx_epoll_del_event(ngx_event
     }
 
     ev->active = 0;
+    ev->posted = 0;
 
     return NGX_OK;
 }
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -235,6 +235,7 @@ static int ngx_kqueue_del_event(ngx_even
 
     ev->active = 0;
     ev->disabled = 0;
+    ev->posted = 0;
 
     if (nchanges > 0
         && ev->index < (u_int) nchanges
@@ -263,7 +264,6 @@ static int ngx_kqueue_del_event(ngx_even
      */
 
     if (flags & NGX_CLOSE_EVENT) {
-        ev->posted = 0;
         return NGX_OK;
     }
 
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -19,7 +19,11 @@ int ngx_poll_process_events(ngx_cycle_t 
 static struct pollfd  *event_list;
 static int             nevents;
 
+#if 0
 static ngx_event_t   **ready_index;
+#endif
+
+static ngx_event_t    *accept_events;
 
 
 static ngx_str_t    poll_name = ngx_string("poll");
@@ -77,6 +81,7 @@ static int ngx_poll_init(ngx_cycle_t *cy
 
         event_list = list;
 
+#if 0
         if (ready_index) {
             ngx_free(ready_index);
         }
@@ -85,6 +90,7 @@ static int ngx_poll_init(ngx_cycle_t *cy
                       ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n,
                                 cycle->log),
                       NGX_ERROR);
+#endif
     }
 
     ngx_io = ngx_os_io;
@@ -100,10 +106,14 @@ static int ngx_poll_init(ngx_cycle_t *cy
 static void ngx_poll_done(ngx_cycle_t *cycle)
 {
     ngx_free(event_list);
+#if 0
     ngx_free(ready_index);
+#endif
 
     event_list = NULL;
+#if 0
     ready_index = NULL;
+#endif
 }
 
 
@@ -168,6 +178,9 @@ static int ngx_poll_del_event(ngx_event_
 
     c = ev->data;
 
+    ev->active = 0;
+    ev->posted = 0;
+
     if (ev->index == NGX_INVALID_INDEX) {
         ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
                       "poll event fd:%d ev:%d is already deleted",
@@ -238,7 +251,6 @@ static int ngx_poll_del_event(ngx_event_
         event_list[e->index].events &= ~event;
     }
 
-    ev->active = 0;
     ev->index = NGX_INVALID_INDEX;
 
     return NGX_OK;
@@ -249,7 +261,7 @@ int ngx_poll_process_events(ngx_cycle_t 
 {
     int                 ready;
     ngx_int_t           i, nready;
-    ngx_uint_t          n, found;
+    ngx_uint_t          n, found, lock, expire;
     ngx_msec_t          timer;
     ngx_err_t           err;
     ngx_cycle_t       **old_cycle;
@@ -260,12 +272,17 @@ int ngx_poll_process_events(ngx_cycle_t 
 
     if (ngx_event_flags & NGX_OVERFLOW_EVENT) {
         timer = 0;
+        expire = 0;
 
     } else {
         timer = ngx_event_find_timer();
 
         if (timer == 0) {
             timer = (ngx_msec_t) INFTIM;
+            expire = 0;
+
+        } else {
+            expire = 1;
         }
     }
 
@@ -277,9 +294,20 @@ int ngx_poll_process_events(ngx_cycle_t 
                        "poll: %d: fd:%d ev:%04X",
                        i, event_list[i].fd, event_list[i].events);
     }
+#endif
+
+    if (ngx_accept_mutex) {
+        if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
+            return NGX_ERROR;
+        }
+
+        if (ngx_accept_mutex_held == 0 && timer > ngx_accept_mutex_delay) {
+            timer = ngx_accept_mutex_delay;
+            expire = 0;
+        }
+    }
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %d", timer);
-#endif
 
     ready = poll(event_list, (u_int) nevents, (int) timer);
 
@@ -301,6 +329,7 @@ int ngx_poll_process_events(ngx_cycle_t 
     if (err) {
         ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
                       cycle->log, err, "poll() failed");
+        ngx_accept_mutex_unlock();
         return NGX_ERROR;
     }
 
@@ -313,6 +342,7 @@ int ngx_poll_process_events(ngx_cycle_t 
         if (ready == 0) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                           "poll() returned no events without timeout");
+            ngx_accept_mutex_unlock();
             return NGX_ERROR;
         }
     }
@@ -322,6 +352,12 @@ int ngx_poll_process_events(ngx_cycle_t 
         return NGX_OK;
     }
 
+    if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+        ngx_accept_mutex_unlock();
+        return NGX_ERROR;
+    }
+
+    lock = 1;
     nready = 0;
 
     for (i = 0; i < nevents && ready; i++) {
@@ -340,7 +376,7 @@ int ngx_poll_process_events(ngx_cycle_t 
         }
 #endif
 
-        if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) {
+        if (event_list[i].revents & (POLLERR|POLLNVAL)) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                           "poll() error fd:%d ev:%04X rev:%04X",
                           event_list[i].fd,
@@ -356,9 +392,9 @@ int ngx_poll_process_events(ngx_cycle_t 
         }
 
         if (event_list[i].fd == -1) {
-
-            /* the disabled event, workaround for our possible bug */
-
+            /*
+             * the disabled event, a workaround for our possible bug, see below
+             */
             continue;
         }
 
@@ -398,12 +434,45 @@ int ngx_poll_process_events(ngx_cycle_t 
 
         if (event_list[i].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) {
             found = 1;
+
+            ev = c->read;
+            ev->ready = 1;
+
+            if (ev->oneshot) {
+                if (ev->timer_set) {
+                    ngx_del_timer(ev);
+                }
+                ngx_poll_del_event(ev, NGX_READ_EVENT, 0);
+            }
+
+            if (ev->accept) {
+                ev->next = accept_events;
+                accept_events = ev;
+            } else {
+                ngx_post_event(ev);
+            }
+
+#if 0
             ready_index[nready++] = c->read;
+#endif
         }
 
         if (event_list[i].revents & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
             found = 1;
+            ev = c->write;
+            ev->ready = 1;
+
+            if (ev->oneshot) {
+                if (ev->timer_set) {
+                    ngx_del_timer(ev);
+                }
+                ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0);
+            }
+
+            ngx_post_event(ev);
+#if 0
             ready_index[nready++] = c->write;
+#endif
         }
 
         if (found) {
@@ -412,6 +481,7 @@ int ngx_poll_process_events(ngx_cycle_t 
         }
     }
 
+#if 0
     for (i = 0; i < nready; i++) {
         ev = ready_index[i];
 
@@ -435,14 +505,55 @@ int ngx_poll_process_events(ngx_cycle_t 
 
         ev->event_handler(ev);
     }
+#endif
+
+    ev = accept_events;
+
+    for ( ;; ) {
+
+        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                      "accept event " PTR_FMT, ev);
+
+        if (ev == NULL) {
+            break;
+        }
+
+        ngx_mutex_unlock(ngx_posted_events_mutex);
+
+        ev->event_handler(ev);
+
+        ev = ev->next;
+
+        if (ev == NULL) {
+            lock = 0;
+            break;
+        }
+
+        if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+            ngx_accept_mutex_unlock();
+            return NGX_ERROR;
+        }
+
+    }
+
+    if (lock) {
+        ngx_mutex_unlock(ngx_posted_events_mutex);
+    }
+
+    ngx_accept_mutex_unlock();
+    accept_events = NULL;
 
     if (ready != 0) {
         ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events");
     }
 
-    if (timer != (ngx_msec_t) INFTIM && delta) {
+    if (expire && delta) {
         ngx_event_expire_timers((ngx_msec_t) delta);
     }
 
+    if (!ngx_threaded) {
+        ngx_event_process_posted(cycle);
+    }
+
     return nready;
 }
--- a/src/event/ngx_event_posted.c
+++ b/src/event/ngx_event_posted.c
@@ -25,8 +25,15 @@ void ngx_event_process_posted(ngx_cycle_
             return;
         }
 
+        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                      "posted event handler " PTR_FMT, ev->event_handler);
+
         ngx_posted_events = ev->next;
 
+        if (ev->accept) {
+            continue;
+        }
+
         if ((!ev->posted && !ev->active)
             || (ev->use_instance && ev->instance != ev->returned_instance))
         {
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -425,7 +425,9 @@ void ngx_http_proxy_check_broken_connect
 
     n = recv(c->fd, buf, 1, MSG_PEEK);
 
-    if (ev->write && n >= 0) {
+    err = ngx_socket_errno;
+
+    if (ev->write && (n >= 0 || err == NGX_EAGAIN)) {
         return;
     }
 
@@ -443,7 +445,6 @@ void ngx_http_proxy_check_broken_connect
     ev->eof = 1;
 
     if (n == -1) {
-        err = ngx_socket_errno;
         if (err == NGX_EAGAIN) {
             return;
         }
@@ -634,11 +635,11 @@ void ngx_http_proxy_close_connection(ngx
         ngx_del_conn(c, NGX_CLOSE_EVENT);
 
     } else {
-        if (c->read->active) {
+        if (c->read->active || c->read->posted) {
             ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
         }
 
-        if (c->write->active) {
+        if (c->write->active || c->read->posted) {
             ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
         }
     }
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -327,19 +327,20 @@ static void ngx_http_proxy_init_upstream
 
     r->connection->read->event_handler = ngx_http_proxy_check_broken_connection;
 
-    if ((ngx_event_flags & (NGX_USE_CLEAR_EVENT|NGX_HAVE_KQUEUE_EVENT))
-        && !r->connection->write->active)
-    {
+    if (ngx_event_flags & (NGX_USE_CLEAR_EVENT|NGX_HAVE_KQUEUE_EVENT)) {
+
         /* kqueue allows to detect when client closes prematurely connection */
 
         r->connection->write->event_handler =
                                         ngx_http_proxy_check_broken_connection;
 
-        if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
+        if (!r->connection->write->active) {
+            if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
                                                 NGX_CLEAR_EVENT) == NGX_ERROR)
-        {
-            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-            return;
+            {
+                ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
         }
     }
 
@@ -560,6 +561,9 @@ static void ngx_http_proxy_connect(ngx_h
 
     rc = ngx_event_connect_peer(&p->upstream->peer);
 
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, p->request->connection->log, 0,
+                   "http proxy connect: %d", rc);
+
     if (rc == NGX_ERROR) {
         ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
         return;
@@ -573,14 +577,13 @@ static void ngx_http_proxy_connect(ngx_h
         return;
     }
 
-    p->upstream->peer.connection->data = p;
-    p->upstream->peer.connection->write->event_handler =
-                                           ngx_http_proxy_send_request_handler;
-    p->upstream->peer.connection->read->event_handler =
-                                   ngx_http_proxy_process_upstream_status_line;
-
     r = p->request;
     c = p->upstream->peer.connection;
+
+    c->data = p;
+    c->write->event_handler = ngx_http_proxy_send_request_handler;
+    c->read->event_handler = ngx_http_proxy_process_upstream_status_line;
+
     c->pool = r->pool;
     c->read->log = c->write->log = c->log = r->connection->log;
 
@@ -613,6 +616,11 @@ static void ngx_http_proxy_connect(ngx_h
 
     if (rc == NGX_AGAIN) {
         ngx_add_timer(c->write, p->lcf->connect_timeout);
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http proxy connect handler: " PTR_FMT,
+                       c->write->event_handler);
+
         return;
     }
 
@@ -638,6 +646,9 @@ static void ngx_http_proxy_send_request(
 
     c = p->upstream->peer.connection;
 
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http proxy send request");
+
 #if (HAVE_KQUEUE)
 
     if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
@@ -715,8 +726,7 @@ static void ngx_http_proxy_send_request(
     }
 #endif
 
-    p->upstream->peer.connection->write->event_handler =
-                                                  ngx_http_proxy_dummy_handler;
+    c->write->event_handler = ngx_http_proxy_dummy_handler;
 
     if (ngx_handle_level_write_event(c->write) == NGX_ERROR) {
         ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -733,6 +743,9 @@ static void ngx_http_proxy_send_request_
     c = wev->data;
     p = c->data;
 
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
+                   "http proxy send request handler");
+
     if (wev->timedout) {
         p->action = "sending request to upstream";
         ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_TIMEOUT);
--- a/src/http/ngx_http_headers.c
+++ b/src/http/ngx_http_headers.c
@@ -22,6 +22,7 @@ ngx_http_header_t  ngx_http_headers_in[]
 #if (NGX_HTTP_GZIP)
     { ngx_string("Accept-Encoding"),
                            offsetof(ngx_http_headers_in_t, accept_encoding) },
+    { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via) },
 #endif
 
     { ngx_string("Authorization"),
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -97,8 +97,7 @@ void ngx_http_init_connection(ngx_connec
                 return;
             }
 
-            rev->next = (ngx_event_t *) ngx_posted_events;
-            ngx_posted_events = rev; 
+            ngx_post_event(rev); 
 
             ngx_mutex_unlock(ngx_posted_events_mutex);
             return;
@@ -1613,11 +1612,11 @@ void ngx_http_close_connection(ngx_conne
         ngx_del_conn(c, NGX_CLOSE_EVENT);
 
     } else {
-        if (c->read->active || c->read->disabled) {
+        if (c->read->active || c->read->posted || c->read->disabled) {
             ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
         }
 
-        if (c->write->active || c->write->disabled) {
+        if (c->write->active || c->write->posted || c->write->disabled) {
             ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
         }
     }
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -100,6 +100,7 @@ typedef struct {
 
 #if (NGX_HTTP_GZIP)
     ngx_table_elt_t  *accept_encoding;
+    ngx_table_elt_t  *via;
 #endif
 
     ngx_table_elt_t  *authorization;