nginx-0.0.1-2002-09-02-18:48:24 import
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 1ea3d22..efa573c 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -19,7 +19,6 @@
 #error "kqueue is not supported on this platform"
 #endif
 
-static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
 
 
 static int              kq;
@@ -50,6 +49,7 @@
 #if !(USE_KQUEUE)
     ngx_event_actions.add = ngx_kqueue_add_event;
     ngx_event_actions.del = ngx_kqueue_del_event;
+    ngx_event_actions.timer = ngx_kqueue_add_timer;
     ngx_event_actions.process = ngx_kqueue_process_events;
 #endif
 
@@ -57,21 +57,11 @@
 
 int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
 {
-    if (event == NGX_TIMER_EVENT) {
-        ngx_add_timer_core(ev, flags);
-        return 0;
-    }
-
     return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
 }
 
 int ngx_kqueue_del_event(ngx_event_t *ev, int event)
 {
-    if (event == NGX_TIMER_EVENT) {
-        ngx_del_timer(ev);
-        return 0;
-    }
-
     return ngx_kqueue_set_event(ev, event, EV_DELETE);
 }
 
@@ -156,14 +146,9 @@
                 delta -= ev->timer_delta;
                 nx = ev->timer_next;
                 ngx_del_timer(ev);
-#if 1
                 ev->timedout = 1;
                 if (ev->event_handler(ev) == NGX_ERROR)
                     ev->close_handler(ev);
-#else
-                if (ev->timer_handler(ev) == -1)
-                    ev->close_handler(ev);
-#endif
                 ev = nx;
             }
 
@@ -182,7 +167,8 @@
 
         if (event_list[i].flags & EV_ERROR) {
             ngx_log_error(NGX_LOG_ALERT, log, event_list[i].data,
-                          "ngx_kqueue_process_events: kevent error");
+                          "ngx_kqueue_process_events: kevent error on %d",
+                          event_list[i].ident);
             continue;
         }
 
@@ -215,10 +201,12 @@
     return 0;
 }
 
-static void ngx_add_timer_core(ngx_event_t *ev, u_int timer)
+void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer)
 {
     ngx_event_t *e;
 
+    ngx_log_debug(ev->log, "set timer: %d" _ timer);
+
     for (e = timer_queue.timer_next;
          e != &timer_queue && timer > e->timer_delta;
          e = e->timer_next)
@@ -232,19 +220,3 @@
     e->timer_prev->timer_next = ev;
     e->timer_prev = ev;
 }
-
-#if 0
-static void ngx_inline ngx_del_timer(ngx_event_t *ev)
-{
-    if (ev->timer_prev)
-        ev->timer_prev->timer_next = ev->timer_next;
-
-    if (ev->timer_next) {
-        ev->timer_next->timer_prev = ev->timer_prev;
-        ev->timer_next = NULL;
-    }
-
-    if (ev->timer_prev)
-        ev->timer_prev = NULL;
-}
-#endif
diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h
index 38509a0..389ff67 100644
--- a/src/event/modules/ngx_kqueue_module.h
+++ b/src/event/modules/ngx_kqueue_module.h
@@ -10,6 +10,7 @@
 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_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 9639a1b..58b8bc8 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -1,5 +1,6 @@
 
 #include <ngx_config.h>
+#include <ngx_core.h>
 #include <ngx_types.h>
 #include <ngx_log.h>
 #include <ngx_time.h>
@@ -7,10 +8,10 @@
 #include <ngx_event.h>
 #include <ngx_select_module.h>
 
-static fd_set       master_read_fds;
-static fd_set       master_write_fds;
-static fd_set       work_read_fds;
-static fd_set       work_write_fds;
+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;
@@ -23,8 +24,6 @@
 static ngx_event_t  timer_queue;
 
 
-static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
-
 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event,
                                      ngx_log_t *log);
 
@@ -42,8 +41,8 @@
         exit(1);
     }
 
-    FD_ZERO(&master_read_fds);
-    FD_ZERO(&master_write_fds);
+    FD_ZERO(&master_read_fd_set);
+    FD_ZERO(&master_write_fd_set);
 
     event_queue.prev = &event_queue;
     event_queue.next = &event_queue;
@@ -53,6 +52,7 @@
 
     ngx_event_actions.add = ngx_select_add_event;
     ngx_event_actions.del = ngx_select_del_event;
+    ngx_event_actions.timer = ngx_select_add_timer;
     ngx_event_actions.process = ngx_select_process_events;
 
 #if (WIN32)
@@ -64,58 +64,76 @@
 
 int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags)
 {
-    fd_set *fds;
-    ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+    ngx_connection_t *c;
 
-    if (event == NGX_TIMER_EVENT) {
-        ngx_add_timer_core(ev, flags);
-        return 0;
+    c = (ngx_connection_t *) ev->data;
+
+    ngx_log_debug(ev->log, "select fd:%d event:%d" _ c->fd _ event);
+
+#if (WIN32)
+    if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE)
+        || (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE))
+    {
+        ngx_log_error(NGX_LOG_ERR, ev->log, 0,
+                      "maximum number of descriptors "
+                      "supported by select() is %d", FD_SETSIZE);
+        return NGX_ERROR;
     }
 
-    ngx_assert((flags != NGX_ONESHOT_EVENT), return -1, ev->log,
-               "ngx_select_add_event: NGX_ONESHOT_EVENT is not supported");
+    if (event == NGX_READ_EVENT) {
+        FD_SET(c->fd, &master_read_fd_set);
+        max_read++;
 
-    fds = ngx_select_get_fd_set(cn->fd, event, ev->log);
-    if (fds == NULL)
-        return -1;
+    } else if (event == NGX_WRITE_EVENT) {
+        FD_SET(c->fd, &master_write_fd_set);
+        max_write++;
+    }
+#else
+    if (event == NGX_READ_EVENT)
+        FD_SET(c->fd, &master_read_fd_set);
+
+    else if (event == NGX_WRITE_EVENT)
+        FD_SET(c->fd, &master_write_fd_set);
+
+    if (max_fd != -1 && max_fd < c->fd)
+        max_fd = c->fd;
+
+#endif
+
+    ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
 
     ev->prev = &event_queue;
     ev->next = event_queue.next;
     event_queue.next->prev = ev;
     event_queue.next = ev;
 
-    FD_SET(cn->fd, fds);
-
-#if (WIN32)
-    switch (event) {
-    case NGX_READ_EVENT:
-        max_read++;
-        break;
-    case NGX_WRITE_EVENT:
-        max_write++;
-        break;
-    }
-#else
-    if (max_fd != -1 && max_fd < cn->fd)
-        max_fd = cn->fd;
-#endif
-
-    return 0;
+    return NGX_OK;
 }
 
 int ngx_select_del_event(ngx_event_t *ev, int event)
 {
-    fd_set *fds;
-    ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+    ngx_connection_t *c;
+    c = (ngx_connection_t *) ev->data;
 
-    if (event == NGX_TIMER_EVENT) {
-        ngx_del_timer(ev);
-        return 0;
+#if (WIN32)
+    if (event == NGX_READ_EVENT) {
+        FD_CLR(c->fd, &master_read_fd_set);
+        max_read--;
+
+    } else if (event == NGX_WRITE_EVENT) {
+        FD_CLR(c->fd, &master_write_fd_set);
+        max_write--;
     }
+#else
+    if (event == NGX_READ_EVENT)
+        FD_CLR(c->fd, &master_read_fd_set);
 
-    fds = ngx_select_get_fd_set(cn->fd, event, ev->log);
-    if (fds == NULL)
-        return -1;
+    else if (event == NGX_WRITE_EVENT)
+        FD_CLR(c->fd, &master_write_fd_set);
+
+    if (max_fd == c->fd)
+        max_fd = -1;
+#endif
 
     if (ev->prev)
         ev->prev->next = ev->next;
@@ -128,70 +146,7 @@
     if (ev->prev)
         ev->next = NULL;
 
-    FD_CLR(cn->fd, fds);
-
-#if (WIN32)
-    switch (event) {
-    case NGX_READ_EVENT:
-        max_read--;
-        break;
-    case NGX_WRITE_EVENT:
-        max_write--;
-        break;
-    }
-#else
-    if (max_fd == cn->fd)
-        max_fd = -1;
-#endif
-
-    return 0;
-}
-
-static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, ngx_log_t *log)
-{
-    ngx_log_debug(log, "ngx_select_get_fd_set: %d %d" _ fd _ event);
-
-#if !(WIN32)
-    if (fd >= FD_SETSIZE) {
-        ngx_log_error(NGX_LOG_ERR, log, 0,
-                      "ngx_select_get_event: maximum descriptor number"
-                      "supported by select() is %d",
-                      FD_SETSIZE - 1);
-        return NULL;
-    }
-#endif
-
-    switch (event) {
-    case NGX_READ_EVENT:
-#if (WIN32)
-        if (max_read >= FD_SETSIZE) {
-            ngx_log_error(NGX_LOG_ERR, log, 0,
-                          "ngx_select_get_event: maximum number of descriptors "
-                          "supported by select() is %d",
-                          FD_SETSIZE);
-            return NULL;
-        }
-#endif
-        return &master_read_fds;
-
-    case NGX_WRITE_EVENT:
-#if (WIN32)
-        if (max_write >= FD_SETSIZE) {
-            ngx_log_error(NGX_LOG_ERR, log, 0,
-                          "ngx_select_get_event: maximum number of descriptors "
-                          "supported by select() is %d",
-                          FD_SETSIZE);
-            return NULL;
-        }
-#endif
-        return &master_write_fds;
-
-    default:
-        ngx_assert(0, return NULL, log,
-                      "ngx_select_get_fd_set: invalid event %d" _ event);
-    }
-
-    return NULL;
+    return NGX_OK;
 }
 
 int ngx_select_process_events(ngx_log_t *log)
@@ -199,11 +154,11 @@
     int                ready, found;
     u_int              timer, delta;
     ngx_event_t       *ev, *nx;
-    ngx_connection_t  *cn;
+    ngx_connection_t  *c;
     struct timeval     tv, *tp;
 
-    work_read_fds = master_read_fds;
-    work_write_fds = master_write_fds;
+    work_read_fd_set = master_read_fd_set;
+    work_write_fd_set = master_write_fd_set;
 
     if (timer_queue.timer_next != &timer_queue) {
         timer = timer_queue.timer_next->timer_delta;
@@ -222,27 +177,27 @@
 #if !(WIN32)
     if (max_fd == -1) {
         for (ev = event_queue.next; ev != &event_queue; ev = ev->next) {
-            cn = (ngx_connection_t *) ev->data;
-            if (max_fd < cn->fd)
-                max_fd = cn->fd;
+            c = (ngx_connection_t *) ev->data;
+            if (max_fd < c->fd)
+                max_fd = c->fd;
         }
 
-        ngx_log_debug(log, "ngx_select_process_events: change max_fd: %d" _
-                      max_fd);
+        ngx_log_debug(log, "change max_fd: %d" _ max_fd);
     }
 #endif
 
     ngx_log_debug(log, "ngx_select_process_events: timer: %d" _ timer);
 
 #if (WIN32)
-    if ((ready = select(0, &work_read_fds, &work_write_fds, NULL, tp))
+    if ((ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp))
 #else
-    if ((ready = select(max_fd + 1, &work_read_fds, &work_write_fds, NULL, tp))
+    if ((ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set,
+                        NULL, tp))
 #endif
                == -1) {
         ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
                      "ngx_select_process_events: select failed");
-        return -1;
+        return NGX_ERROR;
     }
 
     ngx_log_debug(log, "ngx_select_process_events: ready %d" _ ready);
@@ -251,7 +206,7 @@
         delta = ngx_msec() - delta;
 
     } else {
-        ngx_assert((ready != 0), return -1, log,
+        ngx_assert((ready != 0), return NGX_ERROR, log,
                    "ngx_select_process_events: "
                    "select returns no events without timeout");
     }
@@ -268,14 +223,9 @@
                 delta -= ev->timer_delta;
                 nx = ev->timer_next;
                 ngx_del_timer(ev);
-#if 1
                 ev->timedout = 1;
                 if (ev->event_handler(ev) == -1)
                     ev->close_handler(ev);
-#else
-                if (ev->timer_handler(ev) == -1)
-                    ev->close_handler(ev);
-#endif
                 ev = nx;
             }
 
@@ -285,26 +235,35 @@
     }
 
     for (ev = event_queue.next; ev != &event_queue; ev = ev->next) {
-        cn = (ngx_connection_t *) ev->data;
+        c = (ngx_connection_t *) ev->data;
         found = 0;
 
         if (ev->write) {
-            if (FD_ISSET(cn->fd, &work_write_fds)) {
+            if (FD_ISSET(c->fd, &work_write_fd_set)) {
                 ngx_log_debug(log, "ngx_select_process_events: write %d" _
-                              cn->fd);
+                              c->fd);
                 found = 1;
             }
 
         } else {
-            if (FD_ISSET(cn->fd, &work_read_fds)) {
+            if (FD_ISSET(c->fd, &work_read_fd_set)) {
                 ngx_log_debug(log, "ngx_select_process_events: read %d" _
-                              cn->fd);
+                              c->fd);
                 found = 1;
             }
         }
 
         if (found) {
             ev->ready = 1;
+
+            if (ev->oneshot) {
+                ngx_del_timer(ev);
+                if (ev->write)
+                    ngx_select_del_event(ev, NGX_WRITE_EVENT);
+                else
+                    ngx_select_del_event(ev, NGX_READ_EVENT);
+            }
+
             if (ev->event_handler(ev) == -1)
                 ev->close_handler(ev);
 
@@ -313,13 +272,13 @@
 
     }
 
-    ngx_assert((ready == 0), return 0, log,
+    ngx_assert((ready == 0), /* void */ ; , log,
                "ngx_select_process_events: ready != events");
 
-    return 0;
+    return NGX_OK;
 }
 
-static void ngx_add_timer_core(ngx_event_t *ev, u_int timer)
+void ngx_select_add_timer(ngx_event_t *ev, ngx_msec_t timer)
 {
     ngx_event_t *e;
 
@@ -336,19 +295,3 @@
     e->timer_prev->timer_next = ev;
     e->timer_prev = ev;
 }
-
-#if 0
-static void ngx_inline ngx_del_timer(ngx_event_t *ev)
-{
-    if (ev->timer_prev)
-        ev->timer_prev->timer_next = ev->timer_next;
-
-    if (ev->timer_next) {
-        ev->timer_next->timer_prev = ev->timer_prev;
-        ev->timer_next = NULL;
-    }
-
-    if (ev->timer_prev)
-        ev->timer_prev = NULL;
-}
-#endif
diff --git a/src/event/modules/ngx_select_module.h b/src/event/modules/ngx_select_module.h
index 6516981..ea08591 100644
--- a/src/event/modules/ngx_select_module.h
+++ b/src/event/modules/ngx_select_module.h
@@ -10,6 +10,7 @@
 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_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 0d02dfe..5b4fc0b 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -1,6 +1,7 @@
 
 #include <ngx_config.h>
 #include <ngx_types.h>
+#include <ngx_string.h>
 #include <ngx_log.h>
 #include <ngx_alloc.h>
 #include <ngx_listen.h>
@@ -19,7 +20,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;
@@ -78,7 +79,10 @@
         ngx_connections[fd].handler = s[i].handler;
         ngx_connections[fd].log = s[i].log;
 
-        ngx_read_events[fd].log = ngx_connections[fd].log;
+        ngx_test_null(ngx_read_events[fd].log,
+                      ngx_palloc(pool, sizeof(ngx_log_t)), /* void */ ; );
+        ngx_memcpy(ngx_read_events[fd].log, ngx_connections[fd].log,
+                   sizeof(ngx_log_t));
         ngx_read_events[fd].data = &ngx_connections[fd];
         ngx_read_events[fd].event_handler = &ngx_event_accept;
         ngx_read_events[fd].listening = 1;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 9e4bc02..bf19f6c 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -4,6 +4,7 @@
 
 #include <ngx_config.h>
 #include <ngx_types.h>
+#include <ngx_time.h>
 #include <ngx_socket.h>
 #include <ngx_log.h>
 #include <ngx_alloc.h>
@@ -40,11 +41,16 @@
                                 /*   accept: 1 if accept many, 0 otherwise   */
 
     /* flags - int are probably faster on write then bits ??? */
+#if !(USE_KQUEUE)
+    unsigned         oneshot:1;
+#endif
     unsigned         listening:1;
     unsigned         write:1;
 
     unsigned         ready:1;
     unsigned         timedout:1;
+    unsigned         blocked:1;
+
     unsigned         process:1;
     unsigned         read_discarded:1;
 
@@ -72,6 +78,7 @@
 typedef struct {
     int  (*add)(ngx_event_t *ev, int event, u_int flags);
     int  (*del)(ngx_event_t *ev, int event);
+    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);
 /*
@@ -93,21 +100,22 @@
 
 #define NGX_READ_EVENT     EVFILT_READ
 #define NGX_WRITE_EVENT    EVFILT_WRITE
-#define NGX_TIMER_EVENT    (-EVFILT_SYSCOUNT - 1)
 
 #define NGX_LEVEL_EVENT    0
 #define NGX_ONESHOT_EVENT  EV_ONESHOT
+
+#ifndef HAVE_CLEAR_EVENT
+#define HAVE_CLEAR_EVENT   1
 #define NGX_CLEAR_EVENT    EV_CLEAR
+#endif
 
 #else
 
 #define NGX_READ_EVENT     0
 #define NGX_WRITE_EVENT    1
-#define NGX_TIMER_EVENT    2
 
 #define NGX_LEVEL_EVENT    0
 #define NGX_ONESHOT_EVENT  1
-#define NGX_CLEAR_EVENT    2
 
 #endif
 
@@ -116,8 +124,11 @@
 
 #define ngx_init_events      ngx_kqueue_init
 #define ngx_process_events   ngx_kqueue_process_events
-#define ngx_add_event        ngx_kqueue_add_event
-#define ngx_del_event        ngx_kqueue_del_event
+#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_timer        ngx_kqueue_add_timer
 #define ngx_event_recv       ngx_event_recv_core
 
 #else
@@ -126,13 +137,12 @@
 #define ngx_process_events   ngx_event_actions.process
 #define ngx_add_event        ngx_event_actions.add
 #define ngx_del_event        ngx_event_actions.del
+#define ngx_add_timer        ngx_event_actions.timer
 #define ngx_event_recv       ngx_event_recv_core
 
 #endif
 
 
-#define ngx_add_timer(ev, time)  ngx_add_event(ev, NGX_TIMER_EVENT, time)
-
 static void ngx_inline ngx_del_timer(ngx_event_t *ev)
 {
     if (ev->timer_prev)
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 9db1bbd..fd36e35 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -63,7 +63,8 @@
         ngx_connections[s].write = &ngx_write_events[s];
 
         ngx_connections[s].fd = s;
-        ngx_read_events[s].unexpected_eof = 1;
+        ngx_connections[s].unexpected_eof = 1;
+        ngx_write_events[s].write = 1;
         ngx_write_events[s].ready = 1;
 
         ngx_write_events[s].timer = ngx_read_events[s].timer = 10000;
diff --git a/src/event/ngx_event_write.c b/src/event/ngx_event_write.c
index b8411a4..97c0827 100644
--- a/src/event/ngx_event_write.c
+++ b/src/event/ngx_event_write.c
@@ -1,5 +1,6 @@
 
 #include <ngx_config.h>
+#include <ngx_core.h>
 #include <ngx_types.h>
 #include <ngx_alloc.h>
 #include <ngx_array.h>
@@ -10,7 +11,7 @@
 #include <ngx_event_write.h>
 
 
-ngx_chain_t *ngx_event_write(ngx_connection_t *cn, ngx_chain_t *in,
+ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in,
                              off_t flush)
 {
     int           rc;
@@ -24,10 +25,10 @@
     ch = in;
     file = NULL;
 
-    ngx_test_null(header, ngx_create_array(cn->pool, 10, sizeof(ngx_iovec_t)),
+    ngx_test_null(header, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)),
                   (ngx_chain_t *) -1);
 
-    ngx_test_null(trailer, ngx_create_array(cn->pool, 10, sizeof(ngx_iovec_t)),
+    ngx_test_null(trailer, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)),
                   (ngx_chain_t *) -1);
 
     do {
@@ -62,7 +63,7 @@
 
 #if (HAVE_MAX_SENDFILE_IOVEC)
         if (file && header->nelts > HAVE_MAX_SENDFILE_IOVEC) {
-            rc = ngx_sendv(cn->fd, (ngx_iovec_t *) header->elts, header->nelts,
+            rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts, header->nelts,
                            &sent);
         } else {
 #endif
@@ -90,44 +91,57 @@
             }
 
             if (file) {
-                rc = ngx_sendfile(cn->fd,
+                rc = ngx_sendfile(c->fd,
                                   (ngx_iovec_t *) header->elts, header->nelts,
-                                  file->fd, file->pos.file,
+                                  file->file->fd, file->pos.file,
                                   (size_t) (file->last.file - file->pos.file),
                                   (ngx_iovec_t *) trailer->elts, trailer->nelts,
-                                  &sent, cn->log);
+                                  &sent, c->log);
             } else {
-                rc = ngx_sendv(cn->fd, (ngx_iovec_t *) header->elts,
-                               header->nelts, (size_t *) &sent);
-                ngx_log_debug(cn->log, "sendv: %d" _ sent);
+                size_t sendv_sent;
+
+                sendv_sent = 0;
+                rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts,
+                               header->nelts, &sendv_sent);
+                sent = sendv_sent;
+                ngx_log_debug(c->log, "sendv: " QD_FMT _ sent);
             }
 #if (HAVE_MAX_SENDFILE_IOVEC)
         }
 #endif
         /* save sent for logging */
 
-        if (rc == -1)
+        if (rc == NGX_ERROR)
             return (ngx_chain_t *) -1;
 
+        c->sent = sent;
         flush -= sent;
 
         for (ch = in; ch; ch = ch->next) {
+
+            ngx_log_debug(c->log, "ch event write: %x %qx %qd" _
+                          ch->hunk->type _
+                          ch->hunk->pos.file _
+                          ch->hunk->last.file - ch->hunk->pos.file);
+
             if (sent >= ch->hunk->last.file - ch->hunk->pos.file) {
                 sent -= ch->hunk->last.file - ch->hunk->pos.file;
-                ch->hunk->last.file = ch->hunk->pos.file;
+                ch->hunk->pos.file = ch->hunk->last.file;
 
-                ngx_log_debug(cn->log, "event write: %qx 0" _
-                              ch->hunk->pos.file);
+                ngx_log_debug(c->log, "event write: " QX_FMT " 0 " QD_FMT _
+                              ch->hunk->pos.file _ sent);
 
+/*
                 if (ch->hunk->type & NGX_HUNK_LAST)
                    break;
+*/
 
                 continue;
             }
 
             ch->hunk->pos.file += sent;
 
-            ngx_log_debug(cn->log, "event write: %qx %qd" _
+            ngx_log_debug(c->log, "event write: %qx %qd" _
                           ch->hunk->pos.file _
                           ch->hunk->last.file - ch->hunk->pos.file);
 
@@ -135,7 +149,7 @@
         }
 
     /* flush hunks if threaded state */
-    } while (cn->write->context && flush > 0);
+    } while (c->write->context && flush > 0);
 
     ngx_destroy_array(trailer);
     ngx_destroy_array(header);