changeset 114:ac69ab96328d

nginx-0.0.1-2003-07-07-10:11:50 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 07 Jul 2003 06:11:50 +0000
parents d7f606e25b99
children be27f922b9a2
files src/core/nginx.c src/core/ngx_conf_file.c src/core/ngx_conf_file.h src/core/ngx_modules.c src/event/modules/ngx_aio_module.c src/event/modules/ngx_devpoll_module.c src/event/modules/ngx_iocp_module.c src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_poll_module.c src/event/modules/ngx_select_module.c src/event/ngx_event.c src/event/ngx_event.h src/event/ngx_event_accept.c src/event/ngx_event_acceptex.c src/event/ngx_event_timer.c src/http/ngx_http.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_event.c
diffstat 19 files changed, 556 insertions(+), 343 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -7,17 +7,22 @@
 
 static ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle, ngx_log_t *log);
 static int ngx_open_listening_sockets(ngx_cycle_t *cycle, ngx_log_t *log);
-
+static void ngx_clean_old_cycles(ngx_event_t *ev);
 
-void  ****ngx_conf_ctx;
-
+#if (NGX_DEBUG) && (__FreeBSD__)
+extern char *malloc_options;
+#endif
 
-ngx_os_io_t  ngx_io;
-
+int           ngx_max_module;
+ngx_os_io_t   ngx_io;
 
-ngx_cycle_t  ngx_cycle;
+ngx_cycle_t  *ngx_cycle;
+ngx_pool_t   *ngx_temp_pool;
+ngx_array_t   ngx_old_cycles;
+ngx_event_t   ngx_cleaner_event;
 
-int     ngx_max_module;
+/* STUB NAME */
+ngx_connection_t  dumb;
 
 int ngx_connection_counter;
 
@@ -32,6 +37,10 @@ int main(int argc, char *const *argv)
     ngx_log_t    *log;
     ngx_cycle_t  *cycle;
 
+#if (NGX_DEBUG) && (__FreeBSD__)
+    malloc_options = "J";
+#endif
+
     /* TODO */ ngx_max_sockets = -1;
 
     log = ngx_log_init_errlog();
@@ -50,14 +59,14 @@ int main(int argc, char *const *argv)
         return 1;
     }
 
-    ngx_cycle = *cycle;
+    ngx_cycle = cycle;
 
     /* daemon */
 
     /* life cycle */
 
     for ( ;; ) {
-        /* STUB */ ngx_cycle.log->log_level = NGX_LOG_DEBUG;
+        /* STUB */ ngx_cycle->log->log_level = NGX_LOG_DEBUG;
 
         /* forks */
 
@@ -65,7 +74,7 @@ int main(int argc, char *const *argv)
 
         for (i = 0; ngx_modules[i]; i++) {
             if (ngx_modules[i]->init_child) {
-                if (ngx_modules[i]->init_child(&ngx_cycle) == NGX_ERROR) {
+                if (ngx_modules[i]->init_child(ngx_cycle) == NGX_ERROR) {
                     /* fatal */
                     exit(1);
                 }
@@ -80,29 +89,27 @@ int main(int argc, char *const *argv)
         for ( ;; ) {
 
             for ( ;; ) {
-                ngx_log_debug(ngx_cycle.log, "worker cycle");
+                ngx_log_debug(ngx_cycle->log, "worker cycle");
 
-                ngx_process_events(ngx_cycle.log);
+                ngx_process_events(ngx_cycle->log);
 
                 if (rotate) {
-                    ngx_log_debug(ngx_cycle.log, "rotate");
+                    ngx_log_debug(ngx_cycle->log, "rotate");
                 }
 
                 if (restart) {
-                    ngx_log_debug(ngx_cycle.log, "restart");
+                    ngx_log_debug(ngx_cycle->log, "restart");
                     break;
                 }
 
             }
 
-            cycle = ngx_init_cycle(&ngx_cycle, ngx_cycle.log);
+            cycle = ngx_init_cycle(ngx_cycle, ngx_cycle->log);
             if (cycle == NULL) {
                 continue;
             }
 
-ngx_log_debug(ngx_cycle.log, "OPEN: %d" _ cycle->log->file->fd);
-            ngx_cycle = *cycle;
-ngx_log_debug(ngx_cycle.log, "OPEN: %d" _ ngx_cycle.log->file->fd);
+            ngx_cycle = cycle;
             break;
         }
     }
@@ -117,7 +124,7 @@ static ngx_cycle_t *ngx_init_cycle(ngx_c
     ngx_str_t         conf_file;
     ngx_conf_t        conf;
     ngx_pool_t       *pool;
-    ngx_cycle_t      *cycle;
+    ngx_cycle_t      *cycle, **old;
     ngx_open_file_t  *file;
     ngx_listening_t  *ls, *nls;
 
@@ -134,6 +141,8 @@ static ngx_cycle_t *ngx_init_cycle(ngx_c
     }
     cycle->pool = pool;
 
+    cycle->old_cycle = old_cycle;
+
     n = old_cycle ? old_cycle->open_files.nelts : 20;
     cycle->open_files.elts = ngx_pcalloc(pool, n * sizeof(ngx_open_file_t));
     if (cycle->open_files.elts == NULL) {
@@ -178,7 +187,7 @@ static ngx_cycle_t *ngx_init_cycle(ngx_c
 
     conf.ctx = cycle->conf_ctx;
     conf.cycle = cycle;
-    /* STUB */ conf.pool = cycle->pool; ngx_conf_ctx = cycle->conf_ctx;
+    /* STUB */ conf.pool = cycle->pool;
     conf.log = log;
     conf.module_type = NGX_CORE_MODULE;
     conf.cmd_type = NGX_MAIN_CONF;
@@ -193,8 +202,6 @@ static ngx_cycle_t *ngx_init_cycle(ngx_c
 
     failed = 0;
 
-ngx_log_debug(log, "OPEN: %d" _ cycle->log->file->fd);
-
     file = cycle->open_files.elts;
     for (i = 0; i < cycle->open_files.nelts; i++) {
         if (file->name.data == NULL) {
@@ -205,6 +212,8 @@ ngx_log_debug(log, "OPEN: %d" _ cycle->l
                                  NGX_FILE_RDWR,
                                  NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND);
 
+ngx_log_debug(log, "OPEN: %d:%s" _ file->fd _ file->name.data);
+
         if (file->fd == NGX_INVALID_FILE) {
             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                           ngx_open_file_n " \"%s\" failed",
@@ -216,9 +225,7 @@ ngx_log_debug(log, "OPEN: %d" _ cycle->l
         /* TODO: Win32 append */
     }
 
-ngx_log_debug(log, "OPEN: %d" _ cycle->log->file->fd);
-        /* STUB */ cycle->log->log_level = NGX_LOG_DEBUG;
-ngx_log_debug(cycle->log, "TEST");
+    /* STUB */ cycle->log->log_level = NGX_LOG_DEBUG;
 
     if (!failed) {
         if (old_cycle) {
@@ -234,6 +241,7 @@ ngx_log_debug(cycle->log, "TEST");
                                    ls[i].sockaddr, ls[i].socklen) == 0)
                     {
                         nls[n].fd = ls[i].fd;
+                        nls[i].remain = 1;
                         ls[i].remain = 1;
                         break;
                     }
@@ -243,6 +251,12 @@ ngx_log_debug(cycle->log, "TEST");
                     nls[n].new = 1;
                 }
             }
+
+        } else {
+            ls = cycle->listening.elts;
+            for (i = 0; i < cycle->listening.nelts; i++) {
+                ls[i].new = 1;
+            }
         }
 
         if (ngx_open_listening_sockets(cycle, log) == NGX_ERROR) {
@@ -288,6 +302,10 @@ ngx_log_debug(cycle->log, "TEST");
 
     pool->log = cycle->log;
 
+#if 1
+    /* STUB */ cycle->one_process = 1;
+#endif
+
     for (i = 0; ngx_modules[i]; i++) {
         if (ngx_modules[i]->init_module) {
             if (ngx_modules[i]->init_module(cycle) == NGX_ERROR) {
@@ -327,110 +345,54 @@ ngx_log_debug(cycle->log, "TEST");
         }
     }
 
-    ngx_destroy_pool(old_cycle->pool);
+
+    if (!old_cycle->one_process) {
+        ngx_destroy_pool(old_cycle->pool);
+        return cycle;
+    }
+
+    if (ngx_temp_pool == NULL) {
+        ngx_temp_pool = ngx_create_pool(128, cycle->log);
+        if (ngx_temp_pool == NULL) {
+            ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
+                          "can not create ngx_temp_pool");
+            exit(1);
+        }
+
+        n = 10;
+        ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
+                                          n * sizeof(ngx_cycle_t *));
+        if (ngx_old_cycles.elts == NULL) {
+            exit(1);
+        }
+        ngx_old_cycles.nelts = 0;
+        ngx_old_cycles.size = sizeof(ngx_cycle_t *);
+        ngx_old_cycles.nalloc = n;
+        ngx_old_cycles.pool = ngx_temp_pool;
+
+        ngx_cleaner_event.event_handler = ngx_clean_old_cycles;
+        ngx_cleaner_event.log = cycle->log;
+        ngx_cleaner_event.data = &dumb;
+        dumb.fd = -1;
+    }
+
+    ngx_temp_pool->log = cycle->log;
+
+    old = ngx_push_array(&ngx_old_cycles);
+    if (old == NULL) {
+        exit(1);
+    }
+    *old = old_cycle;
+
+    if (!ngx_cleaner_event.timer_set) {
+        ngx_add_timer(&ngx_cleaner_event, 30000);
+        ngx_cleaner_event.timer_set = 1;
+    }
 
     return cycle;
 }
 
 
-
-#if 0
-
-
-int main(int argc, char *const *argv)
-{
-    int          i;
-    ngx_str_t    conf_file;
-    ngx_log_t   *log;
-    ngx_pool_t  *pool, *old_pool;
-    ngx_conf_t   conf;
-
-    ngx_max_sockets = -1;
-
-    log = ngx_log_init_errlog();
-
-    if (ngx_os_init(log) == NGX_ERROR) {
-        return 1;
-    }
-
-    ngx_max_module = 0;
-    for (i = 0; ngx_modules[i]; i++) {
-        ngx_modules[i]->index = ngx_max_module++;
-    }
-
-    /* life cycle */
-
-    {
-        old_pool = pool;
-
-        pool = ngx_create_pool(16 * 1024, log);
-
-        ngx_init_array(ngx_listening_sockets,
-                       pool, 10, sizeof(ngx_listening_t),
-                       1);
-
-        ngx_memzero(&conf, sizeof(ngx_conf_t));
-
-        ngx_test_null(conf.args,
-                      ngx_create_array(pool, 10, sizeof(ngx_str_t)),
-                      1);
-
-        ngx_test_null(ngx_conf_ctx,
-                      ngx_pcalloc(pool, ngx_max_module * sizeof(void *)),
-                      1);
-
-        conf.ctx = ngx_conf_ctx;
-        conf.pool = pool;
-        conf.log = log;
-        conf.module_type = NGX_CORE_MODULE;
-        conf.cmd_type = NGX_MAIN_CONF;
-
-        conf_file.len = sizeof(NGINX_CONF) - 1;
-        conf_file.data = NGINX_CONF;
-
-        if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) {
-            return 1;
-        }
-
-#if 0
-        log = (ngx_log_t *) ngx_get_conf(ngx_errlog_module);
-        /* STUB */ log->log_level = NGX_LOG_DEBUG;
-#endif
-
-        ngx_init_temp_number();
-
-        ngx_io = ngx_os_io;
-
-        for (i = 0; ngx_modules[i]; i++) {
-            if (ngx_modules[i]->init_module) {
-                if (ngx_modules[i]->init_module(pool) == NGX_ERROR) {
-                    return 1;
-                }
-            }
-        }
-
-        if (ngx_open_listening_sockets(log) == NGX_ERROR) {
-            return 1;
-        }
-
-        /* TODO: daemon, once only */
-
-        /* TODO: fork */
-
-        ngx_pre_thread(&ngx_listening_sockets, pool, log);
-
-        /* TODO: threads */
-
-        /* STUB */
-        ngx_worker(log);
-    }
-
-    return 0;
-}
-
-#endif
-
-
 static int ngx_open_listening_sockets(ngx_cycle_t *cycle, ngx_log_t *log)
 {
     int              times, failed, reuseaddr, i;
@@ -549,3 +511,56 @@ static int ngx_open_listening_sockets(ng
 
     return NGX_OK;
 }
+
+
+static void ngx_clean_old_cycles(ngx_event_t *ev)
+{
+    int            i, n, found, live;
+    ngx_cycle_t  **cycle;
+
+    ngx_temp_pool->log = ngx_cycle->log;
+
+    ngx_log_debug(ngx_cycle->log, "clean old cycles");
+
+    live = 0;
+
+    cycle = ngx_old_cycles.elts;
+    for (i = 0; i < ngx_old_cycles.nelts; i++) {
+
+        if (cycle[i] == NULL) {
+            continue;
+        }
+
+        found = 0;
+
+        for (n = 0; n < cycle[i]->connection_n; n++) {
+            if (cycle[i]->connections[n].fd != -1) {
+                found = 1;
+                ngx_log_debug(ngx_cycle->log, "live fd: %d" _ n);
+                break;
+            }
+        }
+
+        if (found) {
+            live = 1;
+            continue;
+        }
+
+        ngx_log_debug(ngx_cycle->log, "clean old cycle: %d" _ i);
+        ngx_destroy_pool(cycle[i]->pool);
+        cycle[i] = NULL;
+    }
+
+    ngx_log_debug(ngx_cycle->log, "old cycles status: %d" _ live);
+
+    if (live) {
+        ngx_log_debug(ngx_cycle->log, "TIMER");
+        ngx_add_timer(ev, 30000);
+
+    } else {
+        ngx_cleaner_event.timer_set = 0;
+        ngx_destroy_pool(ngx_temp_pool);
+        ngx_temp_pool = NULL;
+        ngx_old_cycles.nelts = 0;
+    }
+}
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -25,6 +25,11 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx
     ngx_conf_file_t  *prev;
     ngx_command_t    *cmd;
 
+#if (NGX_SUPPRESS_WARN)
+    fd = NGX_INVALID_FILE;
+    prev = NULL;
+#endif
+
     if (filename) {
 
         /* open configuration file */
@@ -53,6 +58,7 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx
         cf->conf_file->file.fd = fd;
         cf->conf_file->file.name.len = filename->len;
         cf->conf_file->file.name.data = filename->data;
+        cf->conf_file->file.offset = 0;
         cf->conf_file->file.log = cf->log;;
         cf->conf_file->line = 1;
     }
@@ -68,11 +74,11 @@ ngx_log_debug(cf->log, "token %d" _ rc);
 #endif
 
         if (rc == NGX_ERROR) {
-            return NGX_CONF_ERROR;
+            break;
         }
 
         if (rc != NGX_OK) {
-            return NGX_CONF_OK;
+            break;
         }
 
         if (cf->handler) {
@@ -84,7 +90,8 @@ ngx_log_debug(cf->log, "token %d" _ rc);
                 continue;
 
             } else if (rv == NGX_CONF_ERROR) {
-                return NGX_CONF_ERROR;
+                rc = NGX_ERROR;
+                break;
 
             } else {
                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
@@ -92,14 +99,15 @@ ngx_log_debug(cf->log, "token %d" _ rc);
                              rv,
                              cf->conf_file->file.name.data,
                              cf->conf_file->line);
-                return NGX_CONF_ERROR;
+                rc = NGX_ERROR;
+                break;
             }
         }
 
         name = (ngx_str_t *) cf->args->elts;
         found = 0;
 
-        for (m = 0; !found && ngx_modules[m]; m++) {
+        for (m = 0; rc != NGX_ERROR && !found && ngx_modules[m]; m++) {
 
             /* look up the directive in the appropriate modules */
 
@@ -131,7 +139,8 @@ ngx_log_debug(cf->log, "command '%s'" _ 
                                       name->data,
                                       cf->conf_file->file.name.data,
                                       cf->conf_file->line);
-                        return NGX_CONF_ERROR;
+                        rc = NGX_ERROR;
+                        break;
                     }
 
                     /* is the directive's argument count right ? */
@@ -169,7 +178,8 @@ ngx_log_debug(cf->log, "command '%s'" _ 
                                       name->data,
                                       cf->conf_file->file.name.data,
                                       cf->conf_file->line);
-                        return NGX_CONF_ERROR;
+                        rc = NGX_ERROR;
+                        break;
                     }
 
                     /* set up the directive's configuration context */
@@ -198,7 +208,8 @@ ngx_log_debug(cf->log, "rv: %d" _ rv);
                         break;
 
                     } else if (rv == NGX_CONF_ERROR) {
-                        return NGX_CONF_ERROR;
+                        rc = NGX_ERROR;
+                        break;
 
                     } else {
                         if (rv == ngx_conf_errstr) {
@@ -215,7 +226,8 @@ ngx_log_debug(cf->log, "rv: %d" _ rv);
                                          cf->conf_file->line);
                         }
 
-                        return NGX_CONF_ERROR;
+                        rc = NGX_ERROR;
+                        break;
                     }
                 }
 
@@ -230,7 +242,8 @@ ngx_log_debug(cf->log, "rv: %d" _ rv);
                           cf->conf_file->file.name.data,
                           cf->conf_file->line);
 
-            return NGX_CONF_ERROR;
+            rc = NGX_ERROR;
+            break;
         }
     }
 
@@ -245,6 +258,10 @@ ngx_log_debug(cf->log, "rv: %d" _ rv);
         }
     }
 
+    if (rc == NGX_ERROR) {
+        return NGX_CONF_ERROR;
+    }
+
     return NGX_CONF_OK;
 }
 
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -63,13 +63,21 @@ struct ngx_open_file_s {
 
 
 struct ngx_cycle_s {
-    void         ****conf_ctx;
-    ngx_pool_t      *pool;
-    ngx_log_t       *log;
-    ngx_array_t      listening;
-    ngx_array_t      open_files;
+    void           ****conf_ctx;
+    ngx_pool_t        *pool;
+    ngx_log_t         *log;
+    ngx_array_t        listening;
+    ngx_array_t        open_files;
 
-    unsigned         one_process:1;
+    int                connection_n;
+    ngx_connection_t  *connections;
+    ngx_event_t       *read_events;
+    ngx_event_t       *write_events;
+
+    ngx_cycle_t       *cycle;
+    ngx_cycle_t       *old_cycle;
+
+    unsigned           one_process:1;
 };
 
 
@@ -178,7 +186,7 @@ char *ngx_conf_set_time_slot(ngx_conf_t 
 
 
 extern ngx_module_t     *ngx_modules[];
-extern ngx_cycle_t       ngx_cycle;
-
+extern ngx_cycle_t      *ngx_cycle;
+extern ngx_array_t       ngx_old_cycles;
 
 #endif /* _NGX_HTTP_CONF_FILE_H_INCLUDED_ */
--- a/src/core/ngx_modules.c
+++ b/src/core/ngx_modules.c
@@ -53,9 +53,7 @@ ngx_module_t *ngx_modules[] = {
     &ngx_events_module,
     &ngx_event_core_module,
 
-#if 0
     &ngx_select_module,
-#endif
 #if (HAVE_POLL)
     &ngx_poll_module,
 #endif
--- a/src/event/modules/ngx_aio_module.c
+++ b/src/event/modules/ngx_aio_module.c
@@ -9,8 +9,8 @@
 #endif
 
 
-static int ngx_aio_init(ngx_log_t *log);
-static void ngx_aio_done(ngx_log_t *log);
+static int ngx_aio_init(ngx_cycle_t *cycle);
+static void ngx_aio_done(ngx_cycle_t *cycle);
 static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags);
 static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags);
 static int ngx_aio_del_connection(ngx_connection_t *c);
@@ -52,31 +52,33 @@ ngx_module_t  ngx_aio_module = {
     &ngx_aio_module_ctx,                   /* module context */
     NULL,                                  /* module directives */
     NGX_EVENT_MODULE,                      /* module type */
-    NULL                                   /* init module */
+    NULL,                                  /* init module */
+    NULL                                   /* init child */
 };
 
 
 
 #if (HAVE_KQUEUE)
 
-static int ngx_aio_init(ngx_log_t *log)
+static int ngx_aio_init(ngx_cycle_t *cycle)
 {
-    if (ngx_kqueue_module_ctx.actions.init(log) == NGX_ERROR) {
+    if (ngx_kqueue_module_ctx.actions.init(cycle) == NGX_ERROR) {
         return NGX_ERROR;
     }
 
+    ngx_io = ngx_os_aio;
+
     ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_USE_AIO_EVENT;
     ngx_event_actions = ngx_aio_module_ctx.actions;
-    ngx_io = ngx_os_aio;
 
 
     return NGX_OK;
 }
 
 
-static void ngx_aio_done(ngx_log_t *log)
+static void ngx_aio_done(ngx_cycle_t *cycle)
 {
-    ngx_kqueue_module_ctx.actions.done(log);
+    ngx_kqueue_module_ctx.actions.done(cycle);
 }
 
 
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -317,8 +317,9 @@ int ngx_devpoll_process_events(ngx_log_t
     events = ioctl(dp, DP_POLL, &dvp);
 
     if (events == -1) {
-        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "ioctl(DP_POLL) failed");
-        return NGX_ERROR;
+        err = ngx_errno;
+    } else {
+        err = 0;
     }
 
     nchanges = 0;
@@ -326,6 +327,10 @@ int ngx_devpoll_process_events(ngx_log_t
     if ((int) timer != INFTIM) {
         gettimeofday(&tv, NULL);
         delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
+
+#if (NGX_DEBUG_EVENT)
+        ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ delta);
+#endif
         ngx_event_expire_timers(delta);
 
     } else {
@@ -334,11 +339,16 @@ int ngx_devpoll_process_events(ngx_log_t
                           "ioctl(DP_POLL) returns no events without timeout");
             return NGX_ERROR;
         }
-    }
 
 #if (NGX_DEBUG_EVENT)
-    ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ delta);
+        ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ delta);
 #endif
+    }
+
+    if (err) {
+        ngx_log_error(NGX_LOG_ALERT, log, err, "ioctl(DP_POLL) failed");
+        return NGX_ERROR;
+    }
 
     for (i = 0; i < events; i++) {
 
--- a/src/event/modules/ngx_iocp_module.c
+++ b/src/event/modules/ngx_iocp_module.c
@@ -10,13 +10,13 @@
 #include <ngx_iocp_module.h>
 
 
-static int ngx_iocp_init(ngx_log_t *log);
-static void ngx_iocp_done(ngx_log_t *log);
+static int ngx_iocp_init(ngx_cycle_t *cycle);
+static void ngx_iocp_done(ngx_cycle_t *cycle);
 static int ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key);
 static int ngx_iocp_del_connection(ngx_connection_t *c);
 static int ngx_iocp_process_events(ngx_log_t *log);
-static void *ngx_iocp_create_conf(ngx_pool_t *pool);
-static char *ngx_iocp_init_conf(ngx_pool_t *pool, void *conf);
+static void *ngx_iocp_create_conf(ngx_cycle_t *cycle);
+static char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf);
 
 
 static ngx_str_t      iocp_name = ngx_string("iocp");
@@ -72,31 +72,37 @@ ngx_module_t  ngx_iocp_module = {
     &ngx_iocp_module_ctx,                  /* module context */
     ngx_iocp_commands,                     /* module directives */
     NGX_EVENT_MODULE,                      /* module type */
-    NULL                                   /* init module */
+    NULL,                                  /* init module */
+    NULL                                   /* init child */
 };
 
 
 static HANDLE  iocp;
 
 
-static int ngx_iocp_init(ngx_log_t *log)
+static int ngx_iocp_init(ngx_cycle_t *cycle)
 {
     ngx_iocp_conf_t  *cf;
 
-    cf = ngx_event_get_conf(ngx_iocp_module);
-
-    iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, cf->threads);
+    cf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
 
     if (iocp == NULL) {
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+        iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
+                                      cf->threads);
+    }
+
+    if (iocp == NULL) {
+        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                       "CreateIoCompletionPort() failed");
         return NGX_ERROR;
     }
 
-    if (ngx_event_timer_init(log) == NGX_ERROR) {
+    if (ngx_event_timer_init(cycle) == NGX_ERROR) {
         return NGX_ERROR;
     }
 
+    ngx_io = ngx_os_io;
+
     ngx_event_actions = ngx_iocp_module_ctx.actions;
 
     ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_HAVE_IOCP_EVENT;
@@ -105,14 +111,16 @@ static int ngx_iocp_init(ngx_log_t *log)
 }
 
 
-static void ngx_iocp_done(ngx_log_t *log)
+static void ngx_iocp_done(ngx_cycle_t *cycle)
 {
     if (CloseHandle(iocp) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-        "iocp CloseHandle() failed");
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                      "iocp CloseHandle() failed");
     }
 
-    ngx_event_timer_done(log);
+    iocp = NULL;
+
+    ngx_event_timer_done(cycle);
 }
 
 
@@ -177,7 +185,16 @@ static int ngx_iocp_process_events(ngx_l
 
     if (rc == 0) {
         err = ngx_errno;
+    } else {
+        err = 0;
+    }
 
+    if (timer != INFINITE) {
+        delta = ngx_msec() - delta;
+        ngx_event_expire_timers(delta);
+    }
+
+    if (err) {
         if (ovlp == NULL) {
             if (err != WAIT_TIMEOUT) {
                 ngx_log_error(NGX_LOG_ALERT, log, err,
@@ -191,11 +208,6 @@ static int ngx_iocp_process_events(ngx_l
         }
     }
 
-    if (timer != INFINITE) {
-        delta = ngx_msec() - delta;
-        ngx_event_expire_timers(delta);
-    }
-
     if (ovlp) {
         ev = ovlp->event;
 
@@ -224,11 +236,11 @@ ngx_log_debug(log, "iocp ev handler: %08
 }
 
 
-static void *ngx_iocp_create_conf(ngx_pool_t *pool)
+static void *ngx_iocp_create_conf(ngx_cycle_t *cycle)
 {
     ngx_iocp_conf_t  *cf;
 
-    ngx_test_null(cf, ngx_palloc(pool, sizeof(ngx_iocp_conf_t)),
+    ngx_test_null(cf, ngx_palloc(cycle->pool, sizeof(ngx_iocp_conf_t)),
                   NGX_CONF_ERROR);
 
     cf->threads = NGX_CONF_UNSET;
@@ -239,7 +251,7 @@ static void *ngx_iocp_create_conf(ngx_po
 }
 
 
-static char *ngx_iocp_init_conf(ngx_pool_t *pool, void *conf)
+static char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf)
 {
     ngx_iocp_conf_t *cf = conf;
 
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -23,8 +23,8 @@ static int ngx_kqueue_del_event(ngx_even
 static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags);
 static int ngx_kqueue_process_events(ngx_log_t *log);
 
-static void *ngx_kqueue_create_conf(ngx_pool_t *pool);
-static char *ngx_kqueue_init_conf(ngx_pool_t *pool, void *conf);
+static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle);
+static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf);
 
 
 int                    ngx_kqueue = -1;
@@ -311,6 +311,7 @@ static int ngx_kqueue_set_event(ngx_even
 static int ngx_kqueue_process_events(ngx_log_t *log)
 {
     int              events, instance, i;
+    ngx_err_t        err;
     ngx_msec_t       timer, delta;
     ngx_event_t      *ev;
     struct timeval   tv;
@@ -338,8 +339,9 @@ static int ngx_kqueue_process_events(ngx
     events = kevent(ngx_kqueue, change_list, nchanges, event_list, nevents, tp);
 
     if (events == -1) {
-        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "kevent() failed");
-        return NGX_ERROR;
+        err = ngx_errno;
+    } else {
+        err = 0;
     }
 
     nchanges = 0;
@@ -348,6 +350,10 @@ static int ngx_kqueue_process_events(ngx
         gettimeofday(&tv, NULL);
         delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
 
+#if (NGX_DEBUG_EVENT)
+        ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta);
+#endif
+
         /* The expired timers must be handled before a processing of the events
            because the new timers can be added during a processing */
 
@@ -359,11 +365,16 @@ static int ngx_kqueue_process_events(ngx
                           "kevent() returned no events without timeout");
             return NGX_ERROR;
         }
-    }
 
 #if (NGX_DEBUG_EVENT)
-    ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta);
+        ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta);
 #endif
+    }
+
+    if (err) {
+        ngx_log_error(NGX_LOG_ALERT, log, err, "kevent() failed");
+        return NGX_ERROR;
+    }
 
     for (i = 0; i < events; i++) {
 
@@ -439,11 +450,11 @@ static int ngx_kqueue_process_events(ngx
 }
 
 
-static void *ngx_kqueue_create_conf(ngx_pool_t *pool)
+static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle)
 {
     ngx_kqueue_conf_t  *kcf;
 
-    ngx_test_null(kcf, ngx_palloc(pool, sizeof(ngx_kqueue_conf_t)),
+    ngx_test_null(kcf, ngx_palloc(cycle->pool, sizeof(ngx_kqueue_conf_t)),
                   NGX_CONF_ERROR);
 
     kcf->changes = NGX_CONF_UNSET;
@@ -453,7 +464,7 @@ static void *ngx_kqueue_create_conf(ngx_
 }
 
 
-static char *ngx_kqueue_init_conf(ngx_pool_t *pool, void *conf)
+static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf)
 {
     ngx_kqueue_conf_t *kcf = conf;
 
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -9,8 +9,8 @@
 #include <ngx_event.h>
 
 
-static int ngx_poll_init(ngx_log_t *log);
-static void ngx_poll_done(ngx_log_t *log);
+static int ngx_poll_init(ngx_cycle_t *cycle);
+static void ngx_poll_done(ngx_cycle_t *cycle);
 static int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags);
 static int ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags);
 static int ngx_poll_process_events(ngx_log_t *log);
@@ -49,35 +49,64 @@ ngx_module_t  ngx_poll_module = {
     &ngx_poll_module_ctx,                  /* module context */
     NULL,                                  /* module directives */
     NGX_EVENT_MODULE,                      /* module type */
-    NULL                                   /* init module */
+    NULL,                                  /* init module */
+    NULL                                   /* init child */
 };
 
 
 
-static int ngx_poll_init(ngx_log_t *log)
+static int ngx_poll_init(ngx_cycle_t *cycle)
 {
-    ngx_event_conf_t  *ecf;
+    struct pollfd   *list;
+    ngx_event_t    **index;
+
+    if (event_list == NULL) {
+        nevents = 0;
+    }
 
-    ecf = ngx_event_get_conf(ngx_event_core_module);
+    if (cycle->old_cycle == NULL 
+        || cycle->old_cycle->connection_n < cycle->connection_n)
+    {
+        ngx_test_null(list,
+                      ngx_alloc(sizeof(struct pollfd) * cycle->connection_n,
+                                cycle->log),
+                      NGX_ERROR);
 
-    ngx_test_null(event_list,
-                  ngx_alloc(sizeof(struct pollfd) * ecf->connections, log),
-                  NGX_ERROR);
+        if (event_list) {
+            ngx_memcpy(list, event_list, sizeof(ngx_event_t *) * nevents);
+            ngx_free(event_list);
+        }
+
+        event_list = list;
 
-    ngx_test_null(event_index,
-                  ngx_alloc(sizeof(ngx_event_t *) * ecf->connections, log),
-                  NGX_ERROR);
+        ngx_test_null(index,
+                      ngx_alloc(sizeof(ngx_event_t *) * cycle->connection_n,
+                                cycle->log),
+                      NGX_ERROR);
+
+        if (event_index) {
+            ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents);
+            ngx_free(event_index);
+        }
+
+        event_index = index;
 
-    ngx_test_null(ready_index,
-                  ngx_alloc(sizeof(ngx_event_t *) * 2 * ecf->connections, log),
-                  NGX_ERROR);
+        if (ready_index) {
+            ngx_free(ready_index);
+        }
 
-    nevents = 0;
+        ngx_test_null(ready_index,
+                      ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n,
+                                cycle->log),
+                      NGX_ERROR);
+    }
 
-    if (ngx_event_timer_init(log) == NGX_ERROR) {
+    if (ngx_event_timer_init(cycle) == NGX_ERROR) {
         return NGX_ERROR;
     }
 
+    ngx_io = ngx_os_io;
+
     ngx_event_actions = ngx_poll_module_ctx.actions;
 
     ngx_event_flags = NGX_HAVE_LEVEL_EVENT
@@ -88,13 +117,15 @@ static int ngx_poll_init(ngx_log_t *log)
 }
 
 
-static void ngx_poll_done(ngx_log_t *log)
+static void ngx_poll_done(ngx_cycle_t *cycle)
 {
-    ngx_event_timer_done(log);
+    ngx_event_timer_done(cycle);
 
     ngx_free(event_list);
     ngx_free(event_index);
     ngx_free(ready_index);
+
+    event_list = NULL;
 }
 
 
@@ -191,12 +222,13 @@ static int ngx_poll_del_event(ngx_event_
 
 static int ngx_poll_process_events(ngx_log_t *log)
 {
-    int                ready, found;
-    u_int              i, nready;
-    ngx_msec_t         timer, delta;
-    ngx_err_t          err;
-    ngx_event_t       *ev;
-    ngx_connection_t  *c;
+    int                 ready, found;
+    u_int               i, nready;
+    ngx_msec_t          timer, delta;
+    ngx_err_t           err;
+    ngx_cycle_t       **cycle;
+    ngx_event_t        *ev;
+    ngx_connection_t   *c;
 
     timer = ngx_event_find_timer();
 
@@ -217,15 +249,22 @@ static int ngx_poll_process_events(ngx_l
     ngx_log_debug(log, "poll timer: %d" _ timer);
 #endif
 
-    if ((ready = poll(event_list, nevents, timer)) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "poll() failed");
-        return NGX_ERROR;
+    ready = poll(event_list, nevents, timer);
+
+    if (ready == -1) {
+        err = ngx_errno;
+    } else {
+        err = 0;
     }
 
     ngx_log_debug(log, "poll ready %d" _ ready);
 
     if ((int) timer != INFTIM) {
         delta = ngx_msec() - delta;
+
+#if (NGX_DEBUG_EVENT)
+        ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ delta);
+#endif
         ngx_event_expire_timers(delta);
 
     } else {
@@ -234,16 +273,39 @@ static int ngx_poll_process_events(ngx_l
                           "poll() returns no events without timeout");
             return NGX_ERROR;
         }
-    }
 
 #if (NGX_DEBUG_EVENT)
-    ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ delta);
+        ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ delta);
 #endif
+    }
+
+    if (err) {
+        ngx_log_error(NGX_LOG_ALERT, log, err, "poll() failed");
+        return NGX_ERROR;
+    }
 
     nready = 0;
 
     for (i = 0; i < nevents && ready; i++) {
-        c = &ngx_connections[event_list[i].fd];
+        c = &ngx_cycle->connections[event_list[i].fd];
+
+        if (c->fd == -1) {
+            cycle = ngx_old_cycles.elts;
+            for (i = 0; i < ngx_old_cycles.nelts; i++) {
+                if (cycle[i] == NULL) {
+                    continue;
+                }
+                c = &cycle[i]->connections[event_list[i].fd];
+                if (c->fd != -1) {
+                    break;
+                }
+            }
+        }
+
+        if (c->fd == -1) {
+            ngx_log_error(NGX_LOG_ALERT, log, 0, "unkonwn cycle");
+            exit(1);
+        }
 
 #if (NGX_DEBUG_EVENT)
         ngx_log_debug(log, "poll: fd:%d, ev:%d, rev:%d" _
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -9,13 +9,13 @@
 #include <ngx_event.h>
 
 
-static int ngx_select_init(ngx_log_t *log);
-static void ngx_select_done(ngx_log_t *log);
+static int ngx_select_init(ngx_cycle_t *cycle);
+static void ngx_select_done(ngx_cycle_t *cycle);
 static int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags);
 static int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags);
 static int ngx_select_process_events(ngx_log_t *log);
 
-static char *ngx_select_init_conf(ngx_pool_t *pool, void *conf);
+static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf);
 
 
 static fd_set         master_read_fd_set;
@@ -62,33 +62,50 @@ ngx_module_t  ngx_select_module = {
     &ngx_select_module_ctx,                /* module context */
     NULL,                                  /* module directives */
     NGX_EVENT_MODULE,                      /* module type */
-    NULL                                   /* init module */
+    NULL,                                  /* init module */
+    NULL                                   /* init child */
 };
 
 
-static int ngx_select_init(ngx_log_t *log)
+static int ngx_select_init(ngx_cycle_t *cycle)
 {
-    ngx_event_conf_t  *ecf;
+    ngx_event_t  **index;
 
-    ecf = ngx_event_get_conf(ngx_event_core_module);
-
-    FD_ZERO(&master_read_fd_set);
-    FD_ZERO(&master_write_fd_set);
+    if (event_index == NULL) {
+        FD_ZERO(&master_read_fd_set);
+        FD_ZERO(&master_write_fd_set);
+        nevents = 0;
+    }
 
-    ngx_test_null(event_index,
-                  ngx_alloc(sizeof(ngx_event_t *) * 2 * ecf->connections, log),
-                  NGX_ERROR);
+    if (cycle->old_cycle == NULL
+        || cycle->old_cycle->connection_n < cycle->connection_n)
+    {
+        ngx_test_null(index,
+                      ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n,
+                                cycle->log),
+                      NGX_ERROR);
 
-    ngx_test_null(ready_index,
-                  ngx_alloc(sizeof(ngx_event_t *) * 2 * ecf->connections, log),
-                  NGX_ERROR);
+        if (event_index) {
+            ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents);
+            ngx_free(event_index);
+        }
+        event_index = index;
 
-    nevents = 0;
+        if (ready_index) {
+            ngx_free(ready_index);
+        }
+        ngx_test_null(ready_index,
+                      ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n,
+                      cycle->log),
+                      NGX_ERROR);
+    }
 
-    if (ngx_event_timer_init(log) == NGX_ERROR) {
+    if (ngx_event_timer_init(cycle) == NGX_ERROR) {
         return NGX_ERROR;
     }
 
+    ngx_io = ngx_os_io;
+
     ngx_event_actions = ngx_select_module_ctx.actions;
 
     ngx_event_flags = NGX_HAVE_LEVEL_EVENT
@@ -105,12 +122,14 @@ static int ngx_select_init(ngx_log_t *lo
 }
 
 
-static void ngx_select_done(ngx_log_t *log)
+static void ngx_select_done(ngx_cycle_t *cycle)
 {
-    ngx_event_timer_done(log);
+    ngx_event_timer_done(cycle);
 
     ngx_free(event_index);
     ngx_free(ready_index);
+
+    event_index = NULL;
 }
 
 
@@ -229,6 +248,7 @@ static int ngx_select_process_events(ngx
 {
     int                ready, found;
     u_int              i, nready;
+    ngx_err_t          err;
     ngx_msec_t         timer, delta;
     ngx_event_t       *ev;
     ngx_connection_t  *c;
@@ -277,15 +297,15 @@ static int ngx_select_process_events(ngx
 #endif
 
 #if (WIN32)
-    if ((ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp))
+    ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp);
 #else
-    if ((ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set,
-                        NULL, tp))
+    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, "select() failed");
-        return NGX_ERROR;
+
+    if (ready == -1) {
+        err = ngx_socket_errno;
+    } else {
+        err = 0;
     }
 
 #if (NGX_DEBUG_EVENT)
@@ -295,6 +315,10 @@ static int ngx_select_process_events(ngx
     if (timer) {
         /* TODO: Linux returns time in tv */
         delta = ngx_msec() - delta;
+
+#if (NGX_DEBUG_EVENT)
+        ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ delta);
+#endif
         ngx_event_expire_timers(delta);
 
     } else {
@@ -303,11 +327,17 @@ static int ngx_select_process_events(ngx
                           "select() returns no events without timeout");
             return NGX_ERROR;
         }
-    }
 
 #if (NGX_DEBUG_EVENT)
-    ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ delta);
+        ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ delta);
 #endif
+        ngx_event_expire_timers(delta);
+    }
+
+    if (err) {
+        ngx_log_error(NGX_LOG_ALERT, log, err, "select() failed");
+        return NGX_ERROR;
+    }
 
     nready = 0;
 
@@ -372,11 +402,11 @@ static int ngx_select_process_events(ngx
 }
 
 
-static char *ngx_select_init_conf(ngx_pool_t *pool, void *conf)
+static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf)
 {
     ngx_event_conf_t  *ecf;
 
-    ecf = ngx_event_get_conf(ngx_event_core_module);
+    ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
 
     /* the default FD_SETSIZE is 1024U in FreeBSD 5.x */
 
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -21,23 +21,16 @@ extern ngx_module_t ngx_devpoll_module;
 #include <ngx_aio_module.h>
 #endif
 
-static int ngx_event_init_module(ngx_cycle_t *cycle);
-static int ngx_event_init_child(ngx_cycle_t *cycle);
 static int ngx_event_init(ngx_cycle_t *cycle);
-
 static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static void *ngx_event_create_conf(ngx_pool_t *pool);
-static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf);
+static void *ngx_event_create_conf(ngx_cycle_t *cycle);
+static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
 
 
 int                  ngx_event_flags;
 ngx_event_actions_t  ngx_event_actions;
 
-int                  ngx_max_connections;
-ngx_connection_t    *ngx_connections;
-ngx_event_t         *ngx_read_events, *ngx_write_events;
-
 
 static int           ngx_event_max_module;
 
@@ -111,32 +104,11 @@ ngx_module_t  ngx_event_core_module = {
     &ngx_event_core_module_ctx,            /* module context */
     ngx_event_core_commands,               /* module directives */
     NGX_EVENT_MODULE,                      /* module type */
-    ngx_event_init_module,                 /* init module */
-    ngx_event_init_child                   /* init child */
+    NULL,                                  /* init module */
+    ngx_event_init                         /* init child */
 };
 
 
-
-static int ngx_event_init_module(ngx_cycle_t *cycle)
-{
-    if (cycle->one_process) {
-        return ngx_event_init(cycle);
-    }
-
-    return NGX_OK;
-}
-
-
-static int ngx_event_init_child(ngx_cycle_t *cycle)
-{
-    if (cycle->one_process) {
-        return NGX_OK;
-    }
-
-    return ngx_event_init(cycle);
-}
-
-
 static int ngx_event_init(ngx_cycle_t *cycle)
 {
     int                  m, i, fd;
@@ -154,6 +126,8 @@ static int ngx_event_init(ngx_cycle_t *c
 ngx_log_debug(cycle->log, "CONN: %d" _ ecf->connections);
 ngx_log_debug(cycle->log, "TYPE: %d" _ ecf->use);
 
+    cycle->connection_n = ecf->connections;
+
     for (m = 0; ngx_modules[m]; m++) {
         if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
             continue;
@@ -168,30 +142,34 @@ ngx_log_debug(cycle->log, "TYPE: %d" _ e
         }
     }
 
-    if (ngx_max_connections && ngx_max_connections < ecf->connections) {
+    if (cycle->old_cycle && cycle->old_cycle->connection_n < ecf->connections) {
         /* TODO: push into delayed array and temporary pool */
-        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "NOT READY");
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "NOT READY: connections");
         exit(1);
     }
 
-    ngx_max_connections = ecf->connections;
-
-    ngx_test_null(ngx_connections,
+    ngx_test_null(cycle->connections,
                   ngx_alloc(sizeof(ngx_connection_t) * ecf->connections,
                             cycle->log),
                   NGX_ERROR);
 
-    ngx_test_null(ngx_read_events,
+    c = cycle->connections;
+    for (i = 0; i < cycle->connection_n; i++) {
+        c[i].fd = -1;
+    }
+
+    ngx_test_null(cycle->read_events,
                   ngx_alloc(sizeof(ngx_event_t) * ecf->connections, cycle->log),
                   NGX_ERROR);
 
-    ngx_test_null(ngx_write_events,
+    ngx_test_null(cycle->write_events,
                   ngx_alloc(sizeof(ngx_event_t) * ecf->connections, cycle->log),
                   NGX_ERROR);
 
     /* for each listening socket */
 
-    for (s = cycle->listening.elts, i = 0; i < cycle->listening.nelts; i++) {
+    s = cycle->listening.elts;
+    for (i = 0; i < cycle->listening.nelts; i++) {
 
         fd = s[i].fd;
 
@@ -201,33 +179,38 @@ ngx_log_debug(cycle->log, "TYPE: %d" _ e
          * so to find a connection we divide a socket number by 4.
          */
 
-        c = &ngx_connections[fd / 4];
-        rev = &ngx_read_events[fd / 4];
-        wev = &ngx_write_events[fd / 4];
-#else
-        c = &ngx_connections[fd];
-        rev = &ngx_read_events[fd];
-        wev = &ngx_write_events[fd];
+        fd /= 4;
 #endif
 
+        c = &cycle->connections[fd];
+        rev = &cycle->read_events[fd];
+        wev = &cycle->write_events[fd];
+
         ngx_memzero(c, sizeof(ngx_connection_t));
         ngx_memzero(rev, sizeof(ngx_event_t));
 
-        c->fd = fd;
+        c->fd = s[i].fd;
         c->listening = &s[i];
 
         c->ctx = s[i].ctx;
         c->servers = s[i].servers;
         c->log = s[i].log;
+        c->read = rev;
 
+        /* required by iocp in "c->write->active = 1" */
+        c->write = wev;
+
+#if 0
         ngx_test_null(rev->log, ngx_palloc(cycle->pool, sizeof(ngx_log_t)),
                       NGX_ERROR);
 
         ngx_memcpy(rev->log, c->log, sizeof(ngx_log_t));
-        c->read = rev;
-        c->write = wev;
+#endif
+
+        rev->log = c->log;
         rev->data = c;
         rev->index = NGX_INVALID_INDEX;
+
 #if 0
         rev->listening = 1;
 #endif
@@ -238,6 +221,21 @@ ngx_log_debug(cycle->log, "TYPE: %d" _ e
         rev->deferred_accept = s[i].deferred_accept;
 #endif
 
+        /* required by poll */
+        wev->index = NGX_INVALID_INDEX;
+
+        if ((ngx_event_flags & NGX_HAVE_IOCP_EVENT) == 0) {
+            if (s[i].remain) {
+
+                if (ngx_del_event(&cycle->old_cycle->read_events[fd],
+                                             NGX_READ_EVENT, 0) == NGX_ERROR) {
+                    return NGX_ERROR;
+                }
+
+                cycle->old_cycle->connections[fd].fd = -1;
+            }
+        }
+
 #if (WIN32)
 
         if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
@@ -247,7 +245,7 @@ ngx_log_debug(cycle->log, "TYPE: %d" _ e
                 return NGX_ERROR;
             }
 
-            iocpcf = ngx_event_get_conf(ngx_iocp_module);
+            iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
             if (ngx_event_post_acceptex(&s[i], iocpcf->acceptex) == NGX_ERROR) {
                 return NGX_ERROR;
             }
@@ -305,7 +303,7 @@ static char *ngx_events_block(ngx_conf_t
 
         if (module->create_conf) {
             ngx_test_null((*ctx)[ngx_modules[m]->ctx_index],
-                          module->create_conf(cf->pool),
+                          module->create_conf(cf->cycle),
                           NGX_CONF_ERROR);
         }
     }
@@ -328,7 +326,8 @@ static char *ngx_events_block(ngx_conf_t
         module = ngx_modules[m]->ctx;
 
         if (module->init_conf) {
-            rv = module->init_conf(cf->pool, (*ctx)[ngx_modules[m]->ctx_index]);
+            rv = module->init_conf(cf->cycle,
+                                   (*ctx)[ngx_modules[m]->ctx_index]);
             if (rv != NGX_CONF_OK) {
                 return rv;
             }
@@ -371,11 +370,11 @@ static char *ngx_event_use(ngx_conf_t *c
 }
 
 
-static void *ngx_event_create_conf(ngx_pool_t *pool)
+static void *ngx_event_create_conf(ngx_cycle_t *cycle)
 {
     ngx_event_conf_t  *ecf;
 
-    ngx_test_null(ecf, ngx_palloc(pool, sizeof(ngx_event_conf_t)),
+    ngx_test_null(ecf, ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t)),
                   NGX_CONF_ERROR);
 
     ecf->connections = NGX_CONF_UNSET;
@@ -386,7 +385,7 @@ static void *ngx_event_create_conf(ngx_p
 }
 
 
-static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf)
+static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
 {
     ngx_event_conf_t *ecf = conf;
 
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -308,10 +308,6 @@ typedef struct {
 
 
 
-extern ngx_event_t          *ngx_read_events;
-extern ngx_event_t          *ngx_write_events;
-extern ngx_connection_t     *ngx_connections;
-
 #if !(USE_KQUEUE)
 extern ngx_event_actions_t   ngx_event_actions;
 extern ngx_event_type_e      ngx_event_type;
@@ -337,8 +333,8 @@ typedef struct {
 typedef struct {
     ngx_str_t              *name;
 
-    void                 *(*create_conf)(ngx_pool_t *p);
-    char                 *(*init_conf)(ngx_pool_t *p, void *conf);
+    void                 *(*create_conf)(ngx_cycle_t *cycle);
+    char                 *(*init_conf)(ngx_cycle_t *cycle, void *conf);
 
     ngx_event_actions_t     actions;
 } ngx_event_module_t;
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -17,7 +17,7 @@ void ngx_event_accept(ngx_event_t *ev)
     ngx_connection_t  *c, *ls;
     ngx_event_conf_t  *ecf;
 
-    ecf = ngx_event_get_conf(ngx_cycle.conf_ctx, ngx_event_core_module);
+    ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
 
     ls = ev->data;
 
@@ -134,17 +134,18 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->l
 
         if (s % 4) {
             ngx_log_error(NGX_LOG_EMERG, ls->log, 0,
-                          ngx_socket_n " created socket %d", s);
+                          ngx_socket_n
+                          " created socket %d, not divisible by 4", s);
             exit(1);
         }
 
-        rev = &ngx_read_events[s / 4];
-        wev = &ngx_write_events[s / 4];
-        c = &ngx_connections[s / 4];
+        c = &ngx_cycle->connections[s / 4];
+        rev = &ngx_cycle->read_events[s / 4];
+        wev = &ngx_cycle->write_events[s / 4];
 #else
-        rev = &ngx_read_events[s];
-        wev = &ngx_write_events[s];
-        c = &ngx_connections[s];
+        c = &ngx_cycle->connections[s];
+        rev = &ngx_cycle->read_events[s];
+        wev = &ngx_cycle->write_events[s];
 #endif
 
         instance = rev->instance;
@@ -178,12 +179,14 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->l
         c->ctx = ls->ctx;
         c->servers = ls->servers;
 
+#if 0
         c->log = ngx_palloc(c->pool, sizeof(ngx_log_t));
         if (c->log == NULL) {
             return;
         }
         ngx_memcpy(c->log, ev->log, sizeof(ngx_log_t));
-        rev->log = wev->log = c->log;
+#endif
+        rev->log = wev->log = c->log = ev->log;
 
         /* TODO: x86: MT: lock xadd, MP: lock xadd, shared */
         c->number = ngx_connection_counter++;
--- a/src/event/ngx_event_acceptex.c
+++ b/src/event/ngx_event_acceptex.c
@@ -87,17 +87,19 @@ int ngx_event_post_acceptex(ngx_listenin
 
         if (s % 4) {
             ngx_log_error(NGX_LOG_EMERG, ls->log, 0,
-                          ngx_socket_n " created socket %d", s);
+                          ngx_socket_n
+                          " created socket %d, not divisible by 4", s);
+
             exit(1);
         }
 
-        rev = &ngx_read_events[s / 4];
-        wev = &ngx_write_events[s / 4];
-        c = &ngx_connections[s / 4];
+        c = &ngx_cycle->connections[s / 4];
+        rev = &ngx_cycle->read_events[s / 4];
+        wev = &ngx_cycle->write_events[s / 4];
 
+        ngx_memzero(c, sizeof(ngx_connection_t));
         ngx_memzero(rev, sizeof(ngx_event_t));
         ngx_memzero(wev, sizeof(ngx_event_t));
-        ngx_memzero(c, sizeof(ngx_connection_t));
 
         rev->index = wev->index = NGX_INVALID_INDEX;
 
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -4,9 +4,10 @@
 #include <ngx_event.h>
 
 
-static ngx_event_t  *ngx_timer_queue;
+static ngx_event_t  *ngx_timer_queue, ngx_temp_timer_queue;
 static int           ngx_timer_cur_queue;
 static int           ngx_timer_queue_num;
+static int           ngx_expire_timers;
 
 
 int ngx_event_timer_init(ngx_cycle_t *cycle)
@@ -43,10 +44,13 @@ int ngx_event_timer_init(ngx_cycle_t *cy
 
     } else if (ngx_timer_queue_num > ecf->timer_queues) {
         /* STUB */
-        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "NOT READY");
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "NOT READY: timer");
         exit(1);
     }
 
+    ngx_temp_timer_queue.timer_prev = &ngx_temp_timer_queue;
+    ngx_temp_timer_queue.timer_next = &ngx_temp_timer_queue;
+
     return NGX_OK;;
 }
 
@@ -61,7 +65,7 @@ void ngx_event_timer_done(ngx_cycle_t *c
 
 void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
 {
-    ngx_event_t  *e;
+    ngx_event_t  *e, *queue;
 
 #if (NGX_DEBUG_EVENT)
     ngx_connection_t *c = ev->data;
@@ -74,18 +78,24 @@ void ngx_event_add_timer(ngx_event_t *ev
         return;
     }
 
-    for (e = ngx_timer_queue[ngx_timer_cur_queue].timer_next;
-         e != &ngx_timer_queue[ngx_timer_cur_queue] && timer > e->timer_delta;
+    if (ngx_expire_timers) {
+        queue = &ngx_temp_timer_queue;
+
+    } else {
+        queue = &ngx_timer_queue[ngx_timer_cur_queue++];
+
+        if (ngx_timer_cur_queue >= ngx_timer_queue_num) {
+            ngx_timer_cur_queue = 0;
+        }
+    }
+
+    for (e = queue->timer_next;
+         e != queue && timer > e->timer_delta;
          e = e->timer_next)
     {
         timer -= e->timer_delta;
     }
 
-    ngx_timer_cur_queue++;
-    if (ngx_timer_cur_queue >= ngx_timer_queue_num) {
-        ngx_timer_cur_queue = 0;
-    }
-
     ev->timer_delta = timer;
 
     ev->timer_next = e;
@@ -127,6 +137,8 @@ void ngx_event_expire_timers(ngx_msec_t 
     ngx_msec_t    delta;
     ngx_event_t  *ev;
 
+    ngx_expire_timers = 1;
+
     for (i = 0; i < ngx_timer_queue_num; i++) {
 
         delta = timer;
@@ -161,4 +173,20 @@ void ngx_event_expire_timers(ngx_msec_t 
             ev->event_handler(ev);
         }
     }
+
+    ngx_expire_timers = 0;
+
+    if (ngx_temp_timer_queue.timer_next == &ngx_temp_timer_queue) {
+        return;
+    }
+
+    timer = 0;
+
+    while (ngx_temp_timer_queue.timer_next != &ngx_temp_timer_queue) {
+        timer += ngx_temp_timer_queue.timer_next->timer_delta;
+        ev = ngx_temp_timer_queue.timer_next;
+
+        ngx_del_timer(ev);
+        ngx_add_timer(ev, timer);
+    }
 }
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -69,7 +69,6 @@ static char *ngx_http_block(ngx_conf_t *
 
     *(ngx_http_conf_ctx_t **) conf = ctx;
 
-
     /* count the number of the http modules and set up their indices */
 
     ngx_http_max_module = 0;
@@ -273,9 +272,9 @@ static char *ngx_http_block(ngx_conf_t *
                                                    & NGX_HTTP_DEFAULT_SERVER) {
 
                                     ngx_log_error(NGX_LOG_ERR, cf->log, 0,
-                                        "duplicate default server in %s:%d",
-                                        lscf[l].file_name.data,
-                                        lscf[l].line);
+                                           "duplicate default server in %s:%d",
+                                           lscf[l].file_name.data,
+                                           lscf[l].line);
 
                                     return NGX_CONF_ERROR;
                                 }
@@ -471,7 +470,7 @@ static char *ngx_http_block(ngx_conf_t *
             ls->post_accept_timeout = cscf->post_accept_timeout;
 
 #if (WIN32)
-            iocpcf = ngx_event_get_conf(ngx_iocp_module);
+            iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
             if (iocpcf->acceptex_read) {
                 ls->post_accept_buffer_size = cscf->client_header_buffer_size;
             }
@@ -489,7 +488,7 @@ static char *ngx_http_block(ngx_conf_t *
 
                     ngx_test_null(inport,
                                   ngx_palloc(cf->pool,
-                                                   sizeof(ngx_http_in_port_t)),
+                                             sizeof(ngx_http_in_port_t)),
                                   NGX_CONF_ERROR);
 
                     inport->port = in_port[p].port;
@@ -529,7 +528,7 @@ static char *ngx_http_block(ngx_conf_t *
     /* DEBUG STUFF */
     in_port = in_ports.elts;
     for (p = 0; p < in_ports.nelts; p++) {
-ngx_log_debug(cf->log, "port: %d" _ in_port[p].port);
+ngx_log_debug(cf->log, "port: %d %08x" _ in_port[p].port _ &in_port[p]);
         in_addr = in_port[p].addrs.elts;
         for (a = 0; a < in_port[p].addrs.nelts; a++) {
             char ip[20];
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -867,6 +867,7 @@ static void *ngx_http_core_create_loc_co
     lcf->types = NULL;
     lcf->default_type.len = 0;
     lcf->default_type.data = NULL;
+    lcf->err_log = NULL;
 
     */
 
@@ -1050,3 +1051,20 @@ static char *ngx_set_server_name(ngx_con
 
     return NGX_CONF_OK;
 }
+
+
+static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+    ngx_http_core_loc_conf_t *lcf = conf;
+
+    ngx_str_t  *value;
+
+    value = cf->args->elts;
+
+    ngx_test_null(lcf->err_log, ngx_log_create_errlog(cf->cycle),
+                  NGX_CONF_ERROR);
+
+    lcf->err_log->file->name = value[1];
+
+    return NGX_CONF_OK;
+}
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -107,6 +107,7 @@ typedef struct {
     ngx_msec_t    lingering_time;          /* lingering_time */
     ngx_msec_t    lingering_timeout;       /* lingering_timeout */
 
+    ngx_log_t    *err_log;
 } ngx_http_core_loc_conf_t;
 
 
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -152,6 +152,8 @@ static void ngx_http_init_request(ngx_ev
     in_port = c->servers;
     in_addr = in_port->addrs.elts;
 
+ngx_log_debug(rev->log, "IN: %08x" _ in_port);
+
     r->port = in_port->port;
     r->port_name = &in_port->port_name;