nginx-0.0.1-2002-12-15-09:25:09 import
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 3b65f80..4e82162 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -16,12 +16,14 @@
 #endif
 
 
-
+/* should be per-thread */
 static int              kq;
 static struct kevent   *change_list, *event_list;
 static int              nchanges, nevents;
 
 static ngx_event_t      timer_queue;
+/* */
+
 
 int ngx_kqueue_init(int max_connections, ngx_log_t *log)
 {
@@ -53,6 +55,7 @@
     return NGX_OK;
 }
 
+
 int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
 {
     ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
@@ -60,22 +63,33 @@
     return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
 }
 
-int ngx_kqueue_del_event(ngx_event_t *ev, int event)
+
+int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
 {
     ngx_event_t *e;
 
-    if (ev->index <= nchanges && change_list[ev->index].udata == ev) {
-        change_list[ev->index] = change_list[nchanges];
-        e = (ngx_event_t *) change_list[ev->index].udata;
-        e->index = ev->index;
-        nchanges--;
+    if (ev->index < nchanges && change_list[ev->index].udata == ev) {
+
+        ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+        ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _
+                      cn->fd _ event);
+
+        if (ev->index < --nchanges) {
+            e = (ngx_event_t *) change_list[nchanges].udata;
+            change_list[ev->index] = change_list[nchanges];
+            e->index = ev->index;
+        }
 
         return NGX_OK;
     }
 
+    if (flags & NGX_CLOSE_EVENT)
+        return NGX_OK;
+
     return ngx_kqueue_set_event(ev, event, EV_DELETE);
 }
 
+
 int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
 {
     struct timespec  ts = { 0, 0 };
@@ -110,13 +124,18 @@
     return NGX_OK;
 }
 
+
 int ngx_kqueue_process_events(ngx_log_t *log)
 {
     int              events, i;
-    u_int            timer = 0, delta = 0;
+    u_int            timer, delta;
     ngx_event_t      *ev;
     struct timeval   tv;
-    struct timespec  ts, *tp = NULL;
+    struct timespec  ts, *tp;
+
+    timer = 0;
+    delta = 0;
+    tp = NULL;
 
     if (timer_queue.timer_next != &timer_queue) {
         timer = timer_queue.timer_next->timer_delta;
@@ -212,6 +231,7 @@
     return NGX_OK;
 }
 
+
 void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer)
 {
     ngx_event_t *e;
diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h
index ce2aacd..c561920 100644
--- a/src/event/modules/ngx_kqueue_module.h
+++ b/src/event/modules/ngx_kqueue_module.h
@@ -8,7 +8,7 @@
 
 int ngx_kqueue_init(int max_connections, ngx_log_t *log);
 int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags);
-int ngx_kqueue_del_event(ngx_event_t *ev, int event);
+int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags);
 int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags);
 void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer);
 int ngx_kqueue_process_events(ngx_log_t *log);
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index 54a5f7e..c87c592 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -8,24 +8,26 @@
 #include <ngx_event.h>
 #include <ngx_select_module.h>
 
-static fd_set       master_read_fd_set;
-static fd_set       master_write_fd_set;
-static fd_set       work_read_fd_set;
-static fd_set       work_write_fd_set;
+
+/* should be per-thread */
+static fd_set         master_read_fd_set;
+static fd_set         master_write_fd_set;
+static fd_set         work_read_fd_set;
+static fd_set         work_write_fd_set;
 
 #if (WIN32)
-static int          max_read;
-static int          max_write;
+static int            max_read;
+static int            max_write;
 #else
-static int          max_fd;
+static int            max_fd;
 #endif
 
-static int          nevents;
+static int            nevents;
 
 static ngx_event_t  **event_index;
 static ngx_event_t  **ready_index;
 static ngx_event_t    timer_queue;
-
+/* */
 
 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event,
                                      ngx_log_t *log);
@@ -121,12 +123,15 @@
     return NGX_OK;
 }
 
-int ngx_select_del_event(ngx_event_t *ev, int event)
+int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags)
 {
     ngx_connection_t *c;
     c = (ngx_connection_t *) ev->data;
 
-    ngx_log_debug(c->log, "del event: %d" _ c->fd);
+    if (ev->index == NGX_INVALID_INDEX)
+        return NGX_OK;
+
+    ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event);
 
 #if (WIN32)
     if (event == NGX_READ_EVENT) {
@@ -148,13 +153,13 @@
         max_fd = -1;
 #endif
 
-    nevents--;
-
-    if (ev->index < nevents) {
+    if (ev->index < --nevents) {
         event_index[ev->index] = event_index[nevents];
         event_index[ev->index]->index = ev->index;
     }
 
+    ev->index = NGX_INVALID_INDEX;
+
     return NGX_OK;
 }
 
@@ -162,7 +167,7 @@
 {
     int                i, ready, found, nready;
     u_int              timer, delta;
-    ngx_event_t       *ev, *nx;
+    ngx_event_t       *ev;
     ngx_connection_t  *c;
     struct timeval     tv, *tp;
 
@@ -195,6 +200,15 @@
     }
 #endif
 
+#if 1
+    /* DEBUG */
+    for (i = 0; i < nevents; i++) {
+        ev = event_index[i];
+        c = (ngx_connection_t *) ev->data;
+        ngx_log_debug(log, "select: %d" _ c->fd);
+    }
+#endif
+
     ngx_log_debug(log, "select timer: %d" _ timer);
 
 #if (WIN32)
@@ -222,17 +236,17 @@
 
     if (timer) {
         if (delta >= timer) {
-            for (ev = timer_queue.timer_next;
-                 ev != &timer_queue && delta >= ev->timer_delta;
-                 /* void */)
-            {
+            for ( ;; ) {
+                ev = timer_queue.timer_next;
+
+                if (ev == &timer_queue || delta < ev->timer_delta)
+                    break;
+
                 delta -= ev->timer_delta;
-                nx = ev->timer_next;
                 ngx_del_timer(ev);
                 ev->timedout = 1;
-                if (ev->event_handler(ev) == -1)
+                if (ev->event_handler(ev) == NGX_ERROR)
                     ev->close_handler(ev);
-                ev = nx;
             }
 
         } else {
@@ -249,15 +263,13 @@
 
         if (ev->write) {
             if (FD_ISSET(c->fd, &work_write_fd_set)) {
-                ngx_log_debug(log, "select write %d" _
-                              c->fd);
+                ngx_log_debug(log, "select write %d" _ c->fd);
                 found = 1;
             }
 
         } else {
             if (FD_ISSET(c->fd, &work_read_fd_set)) {
-                ngx_log_debug(log, "select read %d" _
-                              c->fd);
+                ngx_log_debug(log, "select read %d" _ c->fd);
                 found = 1;
             }
         }
@@ -274,13 +286,14 @@
 
         if (ev->oneshot) {
             ngx_del_timer(ev);
+
             if (ev->write)
-                ngx_select_del_event(ev, NGX_WRITE_EVENT);
+                ngx_select_del_event(ev, NGX_WRITE_EVENT, 0);
             else
-                ngx_select_del_event(ev, NGX_READ_EVENT);
+                ngx_select_del_event(ev, NGX_READ_EVENT, 0);
         }
 
-        if (ev->event_handler(ev) == -1)
+        if (ev->event_handler(ev) == NGX_ERROR)
             ev->close_handler(ev);
 
         ready--;
diff --git a/src/event/modules/ngx_select_module.h b/src/event/modules/ngx_select_module.h
index e2583d7..7460790 100644
--- a/src/event/modules/ngx_select_module.h
+++ b/src/event/modules/ngx_select_module.h
@@ -8,7 +8,7 @@
 
 int ngx_select_init(int max_connections, ngx_log_t *log);
 int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags);
-int ngx_select_del_event(ngx_event_t *ev, int event);
+int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags);
 int ngx_select_set_event(ngx_event_t *ev, int filter, u_int flags);
 void ngx_select_add_timer(ngx_event_t *ev, ngx_msec_t timer);
 int ngx_select_process_events(ngx_log_t *log);
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 8e918f0..2d68af2 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -21,7 +21,7 @@
 
 #if !(USE_KQUEUE)
 
-#if 0
+#if 1
 ngx_event_type_e     ngx_event_type = NGX_SELECT_EVENT;
 #else
 ngx_event_type_e     ngx_event_type = NGX_KQUEUE_EVENT;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 866911c..db2dc59 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -10,6 +10,8 @@
 #include <ngx_alloc.h>
 #include <ngx_array.h>
 
+#define NGX_INVALID_INDEX  0x80000000
+
 typedef struct ngx_event_s       ngx_event_t;
 
 struct ngx_event_s {
@@ -79,7 +81,7 @@
 
 typedef struct {
     int  (*add)(ngx_event_t *ev, int event, u_int flags);
-    int  (*del)(ngx_event_t *ev, int event);
+    int  (*del)(ngx_event_t *ev, int event, u_int flags);
     void (*timer)(ngx_event_t *ev, ngx_msec_t timer);
     int  (*process)(ngx_log_t *log);
     int  (*read)(ngx_event_t *ev, char *buf, size_t size);
@@ -96,8 +98,12 @@
 NGX_CLEAR_EVENT            kqueue
 NGX_AIO_EVENT              overlapped, aio_read, aioread
                                 no need to add or delete events
+
+NGX_CLOSE_EVENT            kqueue: kqueue deletes events for file that closed
 */
 
+#define NGX_CLOSE_EVENT    1
+
 #if (HAVE_KQUEUE)
 
 #define NGX_READ_EVENT     EVFILT_READ
@@ -124,15 +130,12 @@
 
 #endif
 
-
 #if (USE_KQUEUE)
 
 #define ngx_init_events      ngx_kqueue_init
 #define ngx_process_events   ngx_kqueue_process_events
-#define ngx_kqueue_add_event(ev, event)                                       \
-            ngx_kqueue_set_event(ev, event, EV_ADD | flags)
-#define ngx_kqueue_del_event(ev, event)                                       \
-            ngx_kqueue_set_event(ev, event, EV_DELETE)
+#define ngx_add_event        ngx_kqueue_add_event
+#define ngx_del_event        ngx_kqueue_add_event
 #define ngx_add_timer        ngx_kqueue_add_timer
 #define ngx_event_recv       ngx_event_recv_core
 
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index ef6f85e..9954080 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -1,4 +1,6 @@
 
+#include <nginx.h>
+
 #include <ngx_config.h>
 #include <ngx_core.h>
 #include <ngx_types.h>
@@ -11,11 +13,12 @@
 
 int ngx_event_accept(ngx_event_t *ev)
 {
-    ngx_err_t           err;
-    ngx_socket_t        s;
-    struct sockaddr_in  addr;
-    int addrlen = sizeof(struct sockaddr_in);
-    ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+    ngx_err_t          err;
+    ngx_socket_t       s;
+    ngx_event_t       *rev, *wev;
+    ngx_connection_t  *c, *ac;
+
+    ac = (ngx_connection_t *) ev->data;
             
     ngx_log_debug(ev->log, "ngx_event_accept: accept ready: %d" _
                   ev->available);
@@ -23,69 +26,73 @@
     ev->ready = 0;
   
     do {
-        if ((s = accept(cn->fd, cn->sockaddr, &cn->socklen)) == -1) {
+        if ((s = accept(ac->fd, ac->sockaddr, &ac->socklen)) == -1) {
             err = ngx_socket_errno;
             if (err == NGX_EAGAIN) {
                 ngx_log_error(NGX_LOG_INFO, ev->log, err,
                              "ngx_event_accept: EAGAIN while accept %s",
-                             cn->addr_text);
+                             ac->addr_text);
                 return NGX_OK;
             }
 
             ngx_log_error(NGX_LOG_ERR, ev->log, err,
-                         "ngx_event_accept: accept %s failed", cn->addr_text);
+                         "ngx_event_accept: accept %s failed", ac->addr_text);
             /* if we return NGX_ERROR listen socket would be closed */
             return NGX_OK;
         }
 
-        ngx_log_debug(ev->log, "ngx_event_accept: accept: %d" _ s);
-
 #if !(HAVE_INHERITED_NONBLOCK)
         if (ngx_nonblocking(s) == -1)
             ngx_log_error(NGX_LOG_ERR, log, ngx_socket_errno,
                           ngx_nonblocking_n "failed");
 #endif
 
-        ngx_memzero(&ngx_read_events[s], sizeof(ngx_event_t));
-        ngx_memzero(&ngx_write_events[s], sizeof(ngx_event_t));
-        ngx_memzero(&ngx_connections[s], sizeof(ngx_connection_t));
+        rev = &ngx_read_events[s];
+        wev = &ngx_write_events[s];
+        c = &ngx_connections[s];
 
-        ngx_connections[s].sockaddr = cn->sockaddr;
-        ngx_connections[s].family = cn->family;
-        ngx_connections[s].socklen = cn->socklen;
-        ngx_connections[s].addr = cn->addr;
-        ngx_connections[s].addr_text.len = cn->addr_text.len;
-        ngx_connections[s].post_accept_timeout = cn->post_accept_timeout;
+        ngx_memzero(rev, sizeof(ngx_event_t));
+        ngx_memzero(wev, sizeof(ngx_event_t));
+        ngx_memzero(c, sizeof(ngx_connection_t));
 
-        ngx_read_events[s].data = ngx_write_events[s].data
-                                                         = &ngx_connections[s];
-        ngx_connections[s].read = &ngx_read_events[s];
-        ngx_connections[s].write = &ngx_write_events[s];
+        c->sockaddr = ac->sockaddr;
+        c->family = ac->family;
+        c->socklen = ac->socklen;
+        c->addr = ac->addr;
+        c->addr_text.len = ac->addr_text.len;
+        c->post_accept_timeout = ac->post_accept_timeout;
 
-        ngx_connections[s].fd = s;
-        ngx_connections[s].unexpected_eof = 1;
-        ngx_write_events[s].write = 1;
-        ngx_write_events[s].ready = 1;
+        rev->index = wev->index = NGX_INVALID_INDEX;
 
-        ngx_write_events[s].timer = ngx_read_events[s].timer = 10000;
+        rev->data = wev->data = c;
+        c->read = rev;
+        c->write = wev;
 
-        ngx_write_events[s].timer_handler =
-            ngx_read_events[s].timer_handler = ngx_event_close_connection;
+        c->fd = s;
+        c->unexpected_eof = 1;
+        wev->write = 1;
+        wev->ready = 1;
 
-        ngx_write_events[s].close_handler =
-            ngx_read_events[s].close_handler = ngx_event_close_connection;
+        wev->timer = rev->timer = 10000;
+        wev->timer_handler = rev->timer_handler = ngx_event_close_connection;
+        wev->close_handler = rev->close_handler = ngx_event_close_connection;
 
-        ngx_connections[s].server = cn->server;
-        ngx_connections[s].servers = cn->servers;
-        ngx_connections[s].log =
-            ngx_read_events[s].log = ngx_write_events[s].log = ev->log;
+        c->server = ac->server;
+        c->servers = ac->servers;
+        c->log = rev->log = wev->log = ev->log;
+
+        /* STUB: x86: SP: xadd, MT: lock xadd, MP: lock xadd, shared */
+        c->number = ngx_connection_counter++;
+
+        ngx_log_debug(ev->log, "ngx_event_accept: accept: %d, %d" _
+                                s _ c->number);
 
 #if (HAVE_DEFERRED_ACCEPT)
         if (ev->accept_filter)
-            ngx_read_events[s].ready = 1;
+            rev->ready = 1;
 #endif
 
-        cn->handler(&ngx_connections[s]);
+        ac->handler(c);
 
 #if (HAVE_KQUEUE)
 #if !(USE_KQUEUE)
diff --git a/src/event/ngx_event_close.c b/src/event/ngx_event_close.c
index 0e3fe20..66a3693 100644
--- a/src/event/ngx_event_close.c
+++ b/src/event/ngx_event_close.c
@@ -11,21 +11,20 @@
     int rc;
     ngx_connection_t *c = (ngx_connection_t *) ev->data;
 
+    ngx_log_debug(c->log, "CLOSE: %d" _ c->fd);
+
     ngx_assert((c->fd != -1), return NGX_ERROR, c->log,
                "ngx_event_close: already closed");
 
     ngx_destroy_pool(c->pool);
 
+    ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
+    ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
+
     if ((rc = ngx_close_socket(c->fd)) == -1)
         ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
                       "ngx_event_close: close failed");
 
-    if (c->read->next)
-        ngx_del_event(c->read, NGX_READ_EVENT);
-
-    if (c->write->next)
-        ngx_del_event(c->write, NGX_WRITE_EVENT);
-
     c->fd = -1;
 
     return rc;
diff --git a/src/event/ngx_event_write.c b/src/event/ngx_event_write.c
index ccbb157..5de80d3 100644
--- a/src/event/ngx_event_write.c
+++ b/src/event/ngx_event_write.c
@@ -98,8 +98,7 @@
                                   (ngx_iovec_t *) trailer->elts, trailer->nelts,
                                   &sent, c->log);
             } else {
-                rc = ngx_sendv(c, (ngx_iovec_t *) header->elts,
-                               header->nelts);
+                rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, header->nelts);
 
                 sent = rc > 0 ? rc: 0;