nginx-0.0.3-2004-04-01-20:20:53 import
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 8d37d01..9f0cd18 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -375,7 +375,7 @@
             return NGX_ERROR;
         }
 
-#if 0
+#if 1
         if (ngx_accept_mutex_held == 0 && timer == 0) {
             /* STUB */ timer = 500;
         }
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 5678c84..b50b873 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -28,7 +28,8 @@
 #include <ngx_aio_module.h>
 #endif
 
-static int ngx_event_init(ngx_cycle_t *cycle);
+static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle);
+static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);
 static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 
 static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -39,11 +40,16 @@
 static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
 
 
-int                    ngx_event_flags;
-ngx_event_actions_t    ngx_event_actions;
+static ngx_uint_t                 ngx_event_max_module;
+
+ngx_uint_t                        ngx_event_flags;
+ngx_event_actions_t               ngx_event_actions;
 
 
-static int             ngx_event_max_module;
+ngx_atomic_t                     *ngx_accept_mutex_ptr;
+ngx_atomic_t                     *ngx_accept_mutex;
+ngx_uint_t                        ngx_accept_mutex_held;
+
 
 ngx_thread_volatile ngx_event_t  *ngx_posted_events;
 #if (NGX_THREADS)
@@ -101,6 +107,13 @@
       offsetof(ngx_event_conf_t, multi_accept),
       NULL },
 
+    { ngx_string("accept_mutex"),
+      NGX_EVENT_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_flag_slot,
+      0,
+      offsetof(ngx_event_conf_t, accept_mutex),
+      NULL },
+
       ngx_null_command
 };
 
@@ -119,18 +132,50 @@
     &ngx_event_core_module_ctx,            /* module context */
     ngx_event_core_commands,               /* module directives */
     NGX_EVENT_MODULE,                      /* module type */
-    NULL,                                  /* init module */
-    ngx_event_init                         /* init child */
+    ngx_event_module_init,                 /* init module */
+    ngx_event_process_init                 /* init process */
 };
 
 
-static int ngx_event_init(ngx_cycle_t *cycle)
+static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle)
+{
+    ngx_core_conf_t   *ccf;
+    ngx_event_conf_t  *ecf;
+
+    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+    if (ccf->master == 0) {
+        return NGX_OK;
+    }
+
+    ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
+
+    if (ecf->accept_mutex == 0) {
+        return NGX_OK;
+    }
+
+    ngx_accept_mutex_ptr = mmap(NULL, sizeof(ngx_atomic_t),
+                                PROT_READ|PROT_WRITE,
+                                MAP_ANON|MAP_SHARED, -1, 0);
+
+    if (ngx_accept_mutex_ptr == NULL) {
+        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+                      "mmap(MAP_ANON|MAP_SHARED) failed");
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
 {
     ngx_uint_t           m, i;
     ngx_socket_t         fd;
     ngx_event_t         *rev, *wev;
     ngx_listening_t     *s;
     ngx_connection_t    *c;
+    ngx_core_conf_t     *ccf;
     ngx_event_conf_t    *ecf;
     ngx_event_module_t  *module;
 #if (WIN32)
@@ -138,6 +183,13 @@
 #endif
 
 
+    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+    if (ccf->worker_processes > 1 && ngx_accept_mutex_ptr) {
+        ngx_accept_mutex = ngx_accept_mutex_ptr;
+        ngx_accept_mutex_held = 1;
+    }
+
 #if (NGX_THREADS)
     if (!(ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0))) {
         return NGX_ERROR;
@@ -470,6 +522,7 @@
     ecf->connections = NGX_CONF_UNSET;
     ecf->use = NGX_CONF_UNSET;
     ecf->multi_accept = NGX_CONF_UNSET;
+    ecf->accept_mutex = NGX_CONF_UNSET;
     ecf->name = (void *) NGX_CONF_UNSET;
 
     return ecf;
@@ -542,6 +595,7 @@
     cycle->connection_n = ecf->connections;
 
     ngx_conf_init_value(ecf->multi_accept, 0);
+    ngx_conf_init_value(ecf->accept_mutex, 1);
 
     return NGX_CONF_OK;
 }
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 69a08cd..7fa1a93 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -374,9 +374,12 @@
 
 
 typedef struct {
-    int          connections;
-    int          use;
+    ngx_int_t    connections;
+    ngx_int_t    use;
+
     ngx_flag_t   multi_accept;
+    ngx_flag_t   accept_mutex;
+
     u_char      *name;
 } ngx_event_conf_t;
 
@@ -407,7 +410,7 @@
            }
 
 
-extern int                    ngx_event_flags;
+extern ngx_uint_t             ngx_event_flags;
 extern ngx_module_t           ngx_events_module;
 extern ngx_module_t           ngx_event_core_module;
 
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index d1942d5..41794be 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -14,11 +14,6 @@
 static size_t ngx_accept_log_error(void *data, char *buf, size_t len);
 
 
-ngx_atomic_t  *ngx_accept_mutex_ptr;
-ngx_atomic_t  *ngx_accept_mutex;
-ngx_uint_t     ngx_accept_mutex_held;
-
-
 void ngx_event_accept(ngx_event_t *ev)
 {
     ngx_uint_t             instance, rinstance, winstance, accepted;
diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h
index 21f261f..0eae570 100644
--- a/src/event/ngx_event_timer.h
+++ b/src/event/ngx_event_timer.h
@@ -67,17 +67,28 @@
 
 ngx_inline static void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
 {
-    if (ev->timer_set) {
-        ngx_del_timer(ev);
-    }
+    ngx_int_t  key;
 
-    ev->rbtree_key = (ngx_int_t)
+    key = (ngx_int_t)
               (ngx_elapsed_msec / NGX_TIMER_RESOLUTION * NGX_TIMER_RESOLUTION
                                               + timer) / NGX_TIMER_RESOLUTION;
 #if 0
                              (ngx_elapsed_msec + timer) / NGX_TIMER_RESOLUTION;
 #endif
 
+    if (ev->timer_set) {
+        if (key - ev->rbtree_key < 50) {
+            ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+                           "event timer: %d, old: %d, new: %d",
+                            ngx_event_ident(ev->data), ev->rbtree_key, key);
+            return;
+        }
+
+        ngx_del_timer(ev);
+    }
+
+    ev->rbtree_key = key;
+
     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                    "event timer add: %d: %d",
                     ngx_event_ident(ev->data), ev->rbtree_key);