nginx-0.0.2-2004-03-01-00:03:02 import
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index bfdd98b..c49e198 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -22,6 +22,9 @@
 static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags);
 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);
+#if (NGX_THREADS)
+static void ngx_kqueue_thread_handler(ngx_event_t *ev);
+#endif
 
 static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle);
 static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf);
@@ -68,6 +71,9 @@
         NULL,                              /* add an connection */
         NULL,                              /* delete an connection */
         ngx_kqueue_process_events,         /* process the events */
+#if (NGX_THREADS0)
+        ngx_kqueue_thread_handler,         /* process an event by thread */
+#endif
         ngx_kqueue_init,                   /* init the events */
         ngx_kqueue_done                    /* done the events */
     }
@@ -500,7 +506,12 @@
 
             if (ev->light) {
 
-                /* the accept event */
+                /*
+                 * The light events are the accept event,
+                 * or the event that waits in the mutex queue - we need to
+                 * remove it from the mutex queue before the inserting into
+                 * the posted events queue.
+                 */
 
                 ngx_mutex_unlock(ngx_posted_events_mutex);
 
@@ -538,12 +549,17 @@
 
     /* TODO: non-thread mode only */
 
-    ev = ngx_posted_events;
-    ngx_posted_events = NULL;
+    for ( ;; ) {
 
-    while (ev) {
+        ev = (ngx_event_t *) ngx_posted_events;
+
+        if (ev == NULL) {
+            break;
+        }
+
+        ngx_posted_events = ev->next;
+
         ev->event_handler(ev);
-        ev = ev->next;
     }
 
     return NGX_OK;
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 820a5f5..cfd40d7 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -39,13 +39,13 @@
 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_event_flags;
+ngx_event_actions_t    ngx_event_actions;
 
 
-static int           ngx_event_max_module;
+static int             ngx_event_max_module;
 
-ngx_event_t         *ngx_posted_events;
+volatile ngx_event_t  *ngx_posted_events;
 
 
 static ngx_str_t  events_name = ngx_string("events");
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 899db18..17462df 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -20,6 +20,14 @@
 #endif
 
 
+typedef struct {
+    ngx_uint_t       lock;
+
+    ngx_event_t     *events;
+    ngx_event_t     *last;
+} ngx_event_mutex_t;
+
+
 struct ngx_event_s {
     void            *data;
     /* TODO rename to handler */
@@ -373,11 +381,11 @@
 
 
 
-extern ngx_event_t          *ngx_posted_events;
+extern volatile ngx_event_t  *ngx_posted_events;
 
-extern int                   ngx_event_flags;
-extern ngx_module_t          ngx_events_module;
-extern ngx_module_t          ngx_event_core_module;
+extern int                    ngx_event_flags;
+extern ngx_module_t           ngx_events_module;
+extern ngx_module_t           ngx_event_core_module;
 
 
 #define ngx_event_get_conf(conf_ctx, module)                                  \
diff --git a/src/event/ngx_event_mutex.c b/src/event/ngx_event_mutex.c
index 5a9542b..9f1868f 100644
--- a/src/event/ngx_event_mutex.c
+++ b/src/event/ngx_event_mutex.c
@@ -1,14 +1,65 @@
 
-spinlock_max depend on CPU number and mutex type.
-    1 CPU               1
-    ngx_malloc_mutex    1000 ?
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
 
 
-int ngx_event_mutex_trylock(ngx_mutex_t *mtx)
+ngx_int_t ngx_event_mutex_timedlock(ngx_event_mutex_t *m, ngx_msec_t timer,
+                                    ngx_event_t *ev)
 {
-    for(i = mtx->spinlock_max; i; i--)
-        if (trylock(mtx->lock))
-            return 1;
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+                   "lock event mutex " PTR_FMT " lock:%X", m, m->lock);
 
-    return 0;
+    if (m->lock) {
+
+        if (m->events == NULL) {
+            m->events = ev;
+
+        } else {
+            m->last->next = ev;
+        }
+
+        m->last = ev;
+        ev->next = NULL;
+
+#if (NGX_THREADS)
+        ev->light = 1;
+#endif
+
+        ngx_add_timer(ev, timer);
+
+        return NGX_AGAIN;
+    }
+
+    m->lock = 1;
+
+    return NGX_OK;
+}
+
+
+ngx_int_t ngx_event_mutex_unlock(ngx_event_mutex_t *m, ngx_log_t *log)
+{
+    ngx_event_t  *ev;
+
+    if (m->lock == 0) {
+        ngx_log_error(NGX_LOG_ALERT, log, 0,
+                      "tring to unlock the free event mutex " PTR_FMT, m);
+        return NGX_ERROR;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
+                   "unlock event mutex " PTR_FMT ", next event: " PTR_FMT,
+                   m, m->events);
+
+    m->lock = 0;
+
+    if (m->events) {
+        ev = m->events;
+        m->events = ev->next;
+
+        ev->next = (ngx_event_t *) ngx_posted_events;
+        ngx_posted_events = ev;
+    }
+
+    return NGX_OK;
 }
diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c
index 498fd9f..8983d99 100644
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -9,22 +9,26 @@
 #endif
 
 
-ngx_rbtree_t  *ngx_event_timer_rbtree;
-ngx_rbtree_t   ngx_event_timer_sentinel;
+volatile ngx_rbtree_t  *ngx_event_timer_rbtree;
+ngx_rbtree_t            ngx_event_timer_sentinel;
 
 
 ngx_int_t ngx_event_timer_init(ngx_log_t *log)
 {
     if (ngx_event_timer_rbtree) {
+#if (NGX_THREADS)
         ngx_event_timer_mutex->log = log;
+#endif
         return NGX_OK;
     }
 
     ngx_event_timer_rbtree = &ngx_event_timer_sentinel;
 
+#if (NGX_THREADS)
     if (!(ngx_event_timer_mutex = ngx_mutex_init(log, 0))) {
         return NGX_ERROR;
     }
+#endif
 
     return NGX_OK;
 }
@@ -44,7 +48,8 @@
     }
 #endif
 
-    node = ngx_rbtree_min(ngx_event_timer_rbtree, &ngx_event_timer_sentinel);
+    node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
+                          &ngx_event_timer_sentinel);
 
 #if (NGX_THREADS)
     ngx_mutex_unlock(ngx_event_timer_mutex);
@@ -76,7 +81,7 @@
         }
 #endif
 
-        node = ngx_rbtree_min(ngx_event_timer_rbtree,
+        node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
                               &ngx_event_timer_sentinel);
 
 #if (NGX_THREADS)
diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h
index 300d79c..568a97c 100644
--- a/src/event/ngx_event_timer.h
+++ b/src/event/ngx_event_timer.h
@@ -31,8 +31,8 @@
 #endif
 
 
-extern ngx_rbtree_t  *ngx_event_timer_rbtree;
-extern ngx_rbtree_t   ngx_event_timer_sentinel;
+extern volatile ngx_rbtree_t  *ngx_event_timer_rbtree;
+extern ngx_rbtree_t            ngx_event_timer_sentinel;
 
 
 ngx_inline static void ngx_event_del_timer(ngx_event_t *ev)
@@ -47,7 +47,8 @@
     }
 #endif
 
-    ngx_rbtree_delete(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel,
+    ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree,
+                      &ngx_event_timer_sentinel,
                       (ngx_rbtree_t *) &ev->rbtree_key);
 
 #if (NGX_THREADS)
@@ -87,7 +88,8 @@
     }
 #endif
 
-    ngx_rbtree_insert(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel,
+    ngx_rbtree_insert((ngx_rbtree_t **) &ngx_event_timer_rbtree,
+                      &ngx_event_timer_sentinel,
                       (ngx_rbtree_t *) &ev->rbtree_key);
 
 #if (NGX_THREADS)