nginx-0.0.2-2004-02-23-23:57:12 import
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 005417c..a941899 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -27,6 +27,9 @@
 static void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
 static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
+#if (NGX_THREADS)
+static int ngx_worker_thread_cycle(void *data);
+#endif
 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp);
 static ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
 static ngx_int_t ngx_getopt(ngx_master_ctx_t *ctx, ngx_cycle_t *cycle);
@@ -87,22 +90,22 @@
 };
 
 
-ngx_int_t   ngx_max_module;
-ngx_uint_t  ngx_connection_counter;
+ngx_int_t     ngx_max_module;
+ngx_atomic_t  ngx_connection_counter;
 
-ngx_int_t   ngx_process;
-ngx_pid_t   ngx_pid;
-ngx_pid_t   ngx_new_binary;
+ngx_int_t     ngx_process;
+ngx_pid_t     ngx_pid;
+ngx_pid_t     ngx_new_binary;
 
-ngx_int_t   ngx_inherited;
-ngx_int_t   ngx_reap;
-ngx_int_t   ngx_timer;
-ngx_int_t   ngx_terminate;
-ngx_int_t   ngx_quit;
-ngx_int_t   ngx_noaccept;
-ngx_int_t   ngx_reconfigure;
-ngx_int_t   ngx_reopen;
-ngx_int_t   ngx_change_binary;
+ngx_int_t     ngx_inherited;
+ngx_int_t     ngx_reap;
+ngx_int_t     ngx_timer;
+ngx_int_t     ngx_terminate;
+ngx_int_t     ngx_quit;
+ngx_int_t     ngx_noaccept;
+ngx_int_t     ngx_reconfigure;
+ngx_int_t     ngx_reopen;
+ngx_int_t     ngx_change_binary;
 
 
 int main(int argc, char *const *argv, char **envp)
@@ -577,6 +580,9 @@
     ngx_int_t         i;
     ngx_listening_t  *ls;
     ngx_core_conf_t  *ccf;
+#if (NGX_THREADS)
+    ngx_tid_t         tid;
+#endif
 
     ngx_process = NGX_PROCESS_WORKER;
     ngx_last_process = 0;
@@ -641,7 +647,15 @@
 
     ngx_setproctitle("worker process");
 
-    /* TODO: threads: start ngx_worker_thread_cycle() */
+#if (NGX_THREADS)
+
+    ngx_init_threads(5, 128 * 1024 * 1024, cycle->log);
+
+    for (i = 0; i < 1; i++) {
+        ngx_create_thread(&tid, ngx_worker_thread_cycle, cycle, cycle->log);
+    }
+
+#endif
 
     for ( ;; ) {
         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
@@ -688,6 +702,35 @@
 }
 
 
+#if (NGX_THREADS)
+
+int ngx_worker_thread_cycle(void *data)
+{
+    ngx_cycle_t *cycle = data;
+
+    struct timeval  tv;
+
+    /* STUB */
+
+    ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno,
+                   "thread %d started", ngx_thread_self());
+
+    ngx_setproctitle("worker thread");
+
+    sleep(5);
+
+    ngx_gettimeofday(&tv);
+    ngx_time_update(tv.tv_sec);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno,
+                   "thread %d done", ngx_thread_self());
+
+    return 1;
+}
+
+#endif
+
+
 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp)
 {
     char                *p, *v;
diff --git a/src/core/nginx.h b/src/core/nginx.h
index eb7fe93..6680de1 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -13,7 +13,7 @@
 
 extern ngx_module_t        ngx_core_module;
 
-extern ngx_uint_t          ngx_connection_counter;
+extern ngx_atomic_t        ngx_connection_counter;
 
 extern ngx_int_t           ngx_process;
 
diff --git a/src/core/ngx_atomic.h b/src/core/ngx_atomic.h
index b6bd17f..f5edd19 100644
--- a/src/core/ngx_atomic.h
+++ b/src/core/ngx_atomic.h
@@ -6,9 +6,78 @@
 #include <ngx_core.h>
 
 
+#ifdef __i386__
+
+typedef uint32_t  ngx_atomic_t;
+
+#if (NGX_SMP)
+#define NGX_SMP_LOCK  "lock"
+#else
+#define NGX_SMP_LOCK
+#endif
+
+
+static ngx_inline uint32_t ngx_atomic_inc(ngx_atomic_t *value)
+{
+    uint32_t  old;
+
+    __asm__ __volatile ("
+
+        movl   $1, %0
+    "   NGX_SMP_LOCK
+    "   xaddl  %0, %1
+
+    ": "=a" (old) : "m" (*value));
+
+    return old;
+}
+
+
+static ngx_inline uint32_t ngx_atomic_dec(ngx_atomic_t *value)
+{
+    uint32_t  old;
+
+    __asm__ __volatile ("
+
+        movl   $-1, %0
+    "   NGX_SMP_LOCK
+    "   xaddl  %0, %1
+
+    ": "=a" (old) : "m" (*value));
+
+    return old;
+}
+
+
+static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock,
+                                              ngx_atomic_t old,
+                                              ngx_atomic_t set)
+{
+    uint32_t  res;
+
+    __asm__ __volatile ("
+
+    "   NGX_SMP_LOCK
+    "   cmpxchgl  %3, %1
+        setzb     %%al
+        movzbl    %%al, %0
+
+    ": "=a" (res) : "m" (*lock), "a" (old), "q" (set));
+
+    return res;
+}
+
+#else
+
+typedef uint32_t  ngx_atomic_t;
+
 /* STUB */
 #define ngx_atomic_inc(x)   x++;
 #define ngx_atomic_dec(x)   x--;
+#define ngx_atomic_cmp_set(lock, old, set)   1;
+/**/
+
+#endif
 
 
 #endif /* _NGX_ATOMIC_H_INCLUDED_ */
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 83f410a..67e17d0 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -38,11 +38,6 @@
 #endif
 
 
-/* STUB: ngx_mutex.h */
-#define ngx_mutex_lock(m)
-#define ngx_mutex_unlock(m)
-
-
 /* STUB: autoconf */
 typedef int    ngx_int_t;
 typedef u_int  ngx_uint_t;
@@ -71,7 +66,7 @@
 /* TODO: #ifndef */
 #define NGX_SHUTDOWN_SIGNAL      QUIT
 #define NGX_TERMINATE_SIGNAL     TERM
-#define NGX_NOACCEPT_SIGNAL      ABRT
+#define NGX_NOACCEPT_SIGNAL      WINCH
 #define NGX_RECONFIGURE_SIGNAL   HUP
 #define NGX_REOPEN_SIGNAL        USR1
 #define NGX_CHANGEBIN_SIGNAL     USR2
diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h
index 6bfefcc..f8803c8 100644
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -20,6 +20,7 @@
 #include <ngx_socket.h>
 #include <ngx_errno.h>
 #include <ngx_process.h>
+#include <ngx_thread.h>
 #include <ngx_string.h>
 #include <ngx_parse.h>
 #include <ngx_log.h>
diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c
index 7fdd898..349fe6b 100644
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -79,7 +79,7 @@
 
     /* pid#tid */
     len += ngx_snprintf(errstr + len, max - len,
-                        PID_T_FMT "#%d: ", ngx_pid, /* STUB */ 0);
+                        PID_T_FMT "#" TID_T_FMT ": ", ngx_log_pid, ngx_log_tid);
 
     if (log->data && *(int *) log->data != -1) {
         len += ngx_snprintf(errstr + len, max - len,
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index 9326d2b..43c8c20 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -3,6 +3,11 @@
 #include <ngx_core.h>
 
 
+#if (NGX_THREADS)
+static ngx_mutex_t  *ngx_time_mutex;
+#endif
+
+
 time_t            ngx_cached_time;
 ngx_epoch_msec_t  ngx_elapsed_msec;
 ngx_epoch_msec_t  ngx_old_elapsed_msec;
@@ -46,6 +51,13 @@
     ngx_elapsed_msec = 0;
 
     ngx_time_update(tv.tv_sec);
+
+#if (NGX_THREADS0)
+    if (!(ngx_time_mutex = ngx_mutex_init(log, NGX_MUTEX_LIGHT);
+        return 0;
+    }
+#endif
+
 }
 
 
@@ -57,6 +69,12 @@
         return;
     }
 
+#if (NGX_THREADS0)
+    if (ngx_mutex_trylock(ngx_time_mutex) != NGX_OK) {
+        return;
+    }
+#endif
+
     ngx_cached_time = s;
 
     ngx_gmtime(ngx_cached_time, &ngx_cached_gmtime);
@@ -90,6 +108,11 @@
                                        tm.ngx_tm_hour,
                                        tm.ngx_tm_min,
                                        tm.ngx_tm_sec);
+
+#if (NGX_THREADS0)
+    ngx_mutex_unlock(ngx_time_mutex);
+#endif
+
 }