nginx-0.3.3-RELEASE import

    *) Change: the "bl" and "af" parameters of the "listen" directive was
       renamed to the "backlog" and "accept_filter".

    *) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen"
       directive.

    *) Change: the "$msec" log parameter does not require now the
       additional the gettimeofday() system call.

    *) Feature: the -t switch now tests the "listen" directives.

    *) Bugfix: if the invalid address was specified in the "listen"
       directive, then after the -HUP signal nginx left an open socket in
       the CLOSED state.

    *) Bugfix: the mime type may be incorrectly set to default value for
       index file with variable in the name; the bug had appeared in 0.3.0.

    *) Feature: the "timer_resolution" directive.

    *) Feature: the millisecond "$upstream_response_time" log parameter.

    *) Bugfix: a temporary file with client request body now is removed
       just after the response header was transferred to a client.

    *) Bugfix: OpenSSL 0.9.6 compatibility.

    *) Bugfix: the SSL certificate and key file paths could not be relative.

    *) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in
       the ngx_imap_ssl_module.

    *) Bugfix: the "ssl_protocols" directive allowed to specify the single
       protocol only.
diff --git a/src/os/unix/ngx_atomic.h b/src/os/unix/ngx_atomic.h
index 5856103..3dfce74 100644
--- a/src/os/unix/ngx_atomic.h
+++ b/src/os/unix/ngx_atomic.h
@@ -33,6 +33,8 @@
 
 /* the code in src/os/unix/ngx_sunpro_x86.il */
 
+#define ngx_memory_barrier()        __asm (".volatile"); __asm (".nonvolatile")
+
 
 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
 
@@ -64,6 +66,8 @@
 
 /* the code in src/os/unix/ngx_sunpro_amd64.il */
 
+#define ngx_memory_barrier()        __asm (".volatile"); __asm (".nonvolatile")
+
 
 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
 
diff --git a/src/os/unix/ngx_channel.c b/src/os/unix/ngx_channel.c
index 051f466..c7f1293 100644
--- a/src/os/unix/ngx_channel.c
+++ b/src/os/unix/ngx_channel.c
@@ -207,6 +207,9 @@
     wev->own_lock = &c->lock;
 #endif
 
+    rev->channel = 1;
+    wev->channel = 1;
+
     ev = (event == NGX_READ_EVENT) ? rev : wev;
 
     ev->handler = handler;
diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c
index b7e803b..3c550fb 100644
--- a/src/os/unix/ngx_freebsd_rfork_thread.c
+++ b/src/os/unix/ngx_freebsd_rfork_thread.c
@@ -51,7 +51,8 @@
 static int   errno0;   /* the main thread's errno */
 static int  *errnos;   /* the threads errno's array */
 
-int *__error()
+int *
+__error()
 {
     int  tid;
 
@@ -72,7 +73,8 @@
 
 extern int  __isthreaded;
 
-void _spinlock(ngx_atomic_t *lock)
+void
+_spinlock(ngx_atomic_t *lock)
 {
     ngx_int_t  tries;
 
@@ -107,7 +109,8 @@
 
 #ifndef _spinunlock
 
-void _spinunlock(ngx_atomic_t *lock)
+void
+_spinunlock(ngx_atomic_t *lock)
 {
     *lock = 0;
 }
@@ -115,8 +118,9 @@
 #endif
 
 
-ngx_err_t ngx_create_thread(ngx_tid_t *tid, void* (*func)(void *arg), void *arg,
-                            ngx_log_t *log)
+ngx_err_t
+ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (*func)(void *arg),
+    void *arg, ngx_log_t *log)
 {
     ngx_pid_t   id;
     ngx_err_t   err;
@@ -174,7 +178,8 @@
 }
 
 
-ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
+ngx_int_t
+ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
 {
     char              *red_zone, *zone;
     size_t             len;
@@ -264,7 +269,8 @@
 }
 
 
-ngx_tid_t ngx_thread_self()
+ngx_tid_t
+ngx_thread_self()
 {
     ngx_int_t  tid;
 
@@ -278,7 +284,8 @@
 }
 
 
-ngx_err_t ngx_thread_key_create(ngx_tls_key_t *key)
+ngx_err_t
+ngx_thread_key_create(ngx_tls_key_t *key)
 {
     if (nkeys >= NGX_THREAD_KEYS_MAX) {
         return NGX_ENOMEM;
@@ -290,7 +297,8 @@
 }
 
 
-ngx_err_t ngx_thread_set_tls(ngx_tls_key_t key, void *value)
+ngx_err_t
+ngx_thread_set_tls(ngx_tls_key_t key, void *value)
 {
     if (key >= NGX_THREAD_KEYS_MAX) {
         return NGX_EINVAL;
@@ -301,7 +309,8 @@
 }
 
 
-ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
+ngx_mutex_t *
+ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
 {
     ngx_mutex_t  *m;
     union semun   op;
@@ -342,7 +351,8 @@
 }
 
 
-void ngx_mutex_destroy(ngx_mutex_t *m)
+void
+ngx_mutex_destroy(ngx_mutex_t *m)
 {
     if (semctl(m->semid, 0, IPC_RMID) == -1) {
         ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
@@ -353,7 +363,8 @@
 }
 
 
-ngx_int_t ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try)
+ngx_int_t
+ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try)
 {
     uint32_t       lock, old;
     ngx_uint_t     tries;
@@ -414,7 +425,7 @@
                               "%D threads wait for mutex %p, "
                               "while only %ui threads are available",
                               lock & ~NGX_MUTEX_LOCK_BUSY, m, nthreads);
-                return NGX_ERROR;
+                ngx_abort();
             }
 
             if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
@@ -436,7 +447,7 @@
                 if (semop(m->semid, &op, 1) == -1) {
                     ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
                                  "semop() failed while waiting on mutex %p", m);
-                    return NGX_ERROR;
+                    ngx_abort();
                 }
 
                 ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
@@ -483,13 +494,14 @@
 }
 
 
-ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
+void
+ngx_mutex_unlock(ngx_mutex_t *m)
 {
     uint32_t       lock, old;
     struct sembuf  op;
 
     if (!ngx_threaded) {
-        return NGX_OK;
+        return;
     }
 
     old = m->lock;
@@ -497,7 +509,7 @@
     if (!(old & NGX_MUTEX_LOCK_BUSY)) {
         ngx_log_error(NGX_LOG_ALERT, m->log, 0,
                       "trying to unlock the free mutex %p", m);
-        return NGX_ERROR;
+        ngx_abort();
     }
 
     /* free the mutex */
@@ -521,7 +533,7 @@
         ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
                        "mutex %p is unlocked", m);
 
-        return NGX_OK;
+        return;
     }
 
     /* check whether we need to wake up a waiting thread */
@@ -558,7 +570,7 @@
             if (semop(m->semid, &op, 1) == -1) {
                 ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
                               "semop() failed while waking up on mutex %p", m);
-                return NGX_ERROR;
+                ngx_abort();
             }
 
             break;
@@ -570,11 +582,12 @@
     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
                    "mutex %p is unlocked", m);
 
-    return NGX_OK;
+    return;
 }
 
 
-ngx_cond_t *ngx_cond_init(ngx_log_t *log)
+ngx_cond_t *
+ngx_cond_init(ngx_log_t *log)
 {
     ngx_cond_t  *cv;
 
@@ -592,7 +605,8 @@
 }
 
 
-void ngx_cond_destroy(ngx_cond_t *cv)
+void
+ngx_cond_destroy(ngx_cond_t *cv)
 {
     if (close(cv->kq) == -1) {
         ngx_log_error(NGX_LOG_ALERT, cv->log, ngx_errno,
@@ -603,7 +617,8 @@
 }
 
 
-ngx_int_t ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m)
+ngx_int_t
+ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m)
 {
     int              n;
     ngx_err_t        err;
@@ -647,9 +662,7 @@
         cv->tid = ngx_thread_self();
     }
 
-    if (ngx_mutex_unlock(m) == NGX_ERROR) {
-        return NGX_ERROR;
-    }
+    ngx_mutex_unlock(m);
 
     ngx_log_debug3(NGX_LOG_DEBUG_CORE, cv->log, 0,
                    "cv %p wait, kq:%d, signo:%d", cv, cv->kq, cv->signo);
@@ -703,15 +716,14 @@
 
     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is waked up", cv);
 
-    if (ngx_mutex_lock(m) == NGX_ERROR) {
-        return NGX_ERROR;
-    }
+    ngx_mutex_lock(m);
 
     return NGX_OK;
 }
 
 
-ngx_int_t ngx_cond_signal(ngx_cond_t *cv)
+ngx_int_t
+ngx_cond_signal(ngx_cond_t *cv)
 {
     ngx_err_t  err;
 
diff --git a/src/os/unix/ngx_freebsd_rfork_thread.h b/src/os/unix/ngx_freebsd_rfork_thread.h
index 79e748a..20957a5 100644
--- a/src/os/unix/ngx_freebsd_rfork_thread.h
+++ b/src/os/unix/ngx_freebsd_rfork_thread.h
@@ -55,7 +55,8 @@
 extern size_t   ngx_thread_stack_size;
 
 
-static ngx_inline ngx_int_t ngx_gettid()
+static ngx_inline ngx_int_t
+ngx_gettid()
 {
     char  *sp;
 
@@ -97,7 +98,8 @@
 #define ngx_thread_set_tls_n     "the tls key setting"
 
 
-static void *ngx_thread_get_tls(ngx_tls_key_t key)
+static void *
+ngx_thread_get_tls(ngx_tls_key_t key)
 {   
     if (key >= NGX_THREAD_KEYS_MAX) {
         return NULL;
@@ -108,9 +110,9 @@
 
 
 #define ngx_mutex_trylock(m)  ngx_mutex_dolock(m, 1)
-#define ngx_mutex_lock(m)     ngx_mutex_dolock(m, 0)
+#define ngx_mutex_lock(m)     (void) ngx_mutex_dolock(m, 0)
 ngx_int_t ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try);
-ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m);
+void ngx_mutex_unlock(ngx_mutex_t *m);
 
 
 typedef int (*ngx_rfork_thread_func_pt)(void *arg);
diff --git a/src/os/unix/ngx_gcc_atomic_amd64.h b/src/os/unix/ngx_gcc_atomic_amd64.h
index 07b2d50..374e3b8 100644
--- a/src/os/unix/ngx_gcc_atomic_amd64.h
+++ b/src/os/unix/ngx_gcc_atomic_amd64.h
@@ -72,3 +72,6 @@
 
     return add;
 }
+
+
+#define ngx_memory_barrier()       __asm__ volatile ("" ::: "memory")
diff --git a/src/os/unix/ngx_gcc_atomic_ppc.h b/src/os/unix/ngx_gcc_atomic_ppc.h
index 8fc3bc0..58b24c3 100644
--- a/src/os/unix/ngx_gcc_atomic_ppc.h
+++ b/src/os/unix/ngx_gcc_atomic_ppc.h
@@ -64,3 +64,10 @@
 
     return res;
 }
+
+
+#if (NGX_SMP)
+#define ngx_memory_barrier()   __asm__ volatile ("sync\n" ::: "memory")
+#else
+#define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
+#endif
diff --git a/src/os/unix/ngx_gcc_atomic_sparc64.h b/src/os/unix/ngx_gcc_atomic_sparc64.h
index c7022a9..8314318 100644
--- a/src/os/unix/ngx_gcc_atomic_sparc64.h
+++ b/src/os/unix/ngx_gcc_atomic_sparc64.h
@@ -67,3 +67,13 @@
         old = res;
     }
 }
+
+
+#if (NGX_SMP)
+#define ngx_memory_barrier()                                                  \
+            __asm__ volatile (                                                \
+            "membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad"        \
+            ::: "memory")
+#else
+#define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
+#endif
diff --git a/src/os/unix/ngx_gcc_atomic_x86.h b/src/os/unix/ngx_gcc_atomic_x86.h
index e3c0c93..3053e72 100644
--- a/src/os/unix/ngx_gcc_atomic_x86.h
+++ b/src/os/unix/ngx_gcc_atomic_x86.h
@@ -101,3 +101,11 @@
 }
 
 #endif
+
+
+/*
+ * on x86 the write operations go in a program order, so we need only
+ * to disable the gcc reorder optimizations
+ */
+
+#define ngx_memory_barrier()    __asm__ volatile ("" ::: "memory")
diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h
index d3ef325..ac7d7a8 100644
--- a/src/os/unix/ngx_linux_config.h
+++ b/src/os/unix/ngx_linux_config.h
@@ -98,11 +98,6 @@
 #endif
 
 
-#ifndef NGX_HAVE_SELECT_CHANGE_TIMEOUT
-#define NGX_HAVE_SELECT_CHANGE_TIMEOUT   1
-#endif
-
-
 #define NGX_HAVE_OS_SPECIFIC_INIT    1
 
 
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
index f20f44c..4a2b581 100644
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -50,7 +50,7 @@
         return NGX_ERROR;
     }
     
-    ngx_max_sockets = rlmt.rlim_cur;
+    ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur;
 
 #if (NGX_HAVE_INHERITED_NONBLOCK)
     ngx_inherited_nonblocking = 1;
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
index 07a7c66..5e88ef3 100644
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -282,7 +282,6 @@
 ngx_signal_handler(int signo)
 {
     char            *action;
-    struct timeval   tv;
     ngx_int_t        ignore;
     ngx_err_t        err;
     ngx_signal_t    *sig;
@@ -297,8 +296,7 @@
         }
     }
 
-    ngx_gettimeofday(&tv);
-    ngx_time_update(tv.tv_sec);
+    ngx_time_update(0, 0);
 
     action = "";
 
@@ -456,6 +454,7 @@
             if (err == NGX_ECHILD) {
                 ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, errno,
                               "waitpid() failed");
+                return;
             }
 
 #endif
@@ -527,6 +526,6 @@
         break;
 
     case NGX_DEBUG_POINTS_ABORT:
-        abort();
+        ngx_abort();
     }
 }
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 029de43..f4ec06f 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -21,7 +21,7 @@
 static void ngx_channel_handler(ngx_event_t *ev);
 #if (NGX_THREADS)
 static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle);
-static void *ngx_worker_thread_cycle(void *data);
+static ngx_thread_value_t ngx_worker_thread_cycle(void *data);
 #endif
 #if 0
 static void ngx_garbage_collector_cycle(ngx_cycle_t *cycle, void *data);
@@ -69,7 +69,6 @@
     ngx_int_t          i;
     ngx_uint_t         n;
     sigset_t           set;
-    struct timeval     tv;
     struct itimerval   itv;
     ngx_uint_t         live;
     ngx_msec_t         delay;
@@ -145,8 +144,7 @@
 
         sigsuspend(&set);
 
-        ngx_gettimeofday(&tv);
-        ngx_time_update(tv.tv_sec);
+        ngx_time_update(0, 0);
 
         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "wake up");
 
@@ -275,7 +273,7 @@
     for ( ;; ) {
         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
 
-        ngx_process_events(cycle);
+        ngx_process_events_and_timers(cycle);
 
         if (ngx_terminate || ngx_quit) {
             ngx_master_exit(cycle);
@@ -645,6 +643,8 @@
 static void
 ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
 {
+    ngx_uint_t         i;
+    ngx_connection_t  *c;
 #if (NGX_THREADS)
     ngx_int_t          n;
     ngx_err_t          err;
@@ -657,11 +657,6 @@
 
 #if (NGX_THREADS)
 
-    if (ngx_time_mutex_init(cycle->log) == NGX_ERROR) {
-        /* fatal */
-        exit(2);
-    }
-
     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
 
     if (ngx_threads_n) {
@@ -731,7 +726,7 @@
 
         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
 
-        ngx_process_events(cycle);
+        ngx_process_events_and_timers(cycle);
 
         if (ngx_terminate) {
             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
@@ -740,6 +735,21 @@
             ngx_wakeup_worker_threads(cycle);
 #endif
 
+            c = cycle->connections;
+            for (i = 0; i < cycle->connection_n; i++) {
+                if (c[i].fd != -1
+                    && c[i].read
+                    && !c[i].read->accept
+                    && !c[i].read->channel)
+                {
+                    ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+                                  "open socket #%d left in %ui connection, "
+                                  "aborting",
+                                  c[i].fd, i);
+                    ngx_abort();
+                }
+            }
+
             /*
              * we do not destroy cycle->pool here because a signal handler
              * that uses cycle->log can be called at this point
@@ -1054,7 +1064,7 @@
 }
 
 
-static void *
+static ngx_thread_value_t
 ngx_worker_thread_cycle(void *data)
 {
     ngx_thread_t  *thr = data;
@@ -1075,7 +1085,7 @@
     if (err) {
         ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
                       ngx_thread_sigmask_n " failed");
-        return (void *) 1;
+        return (ngx_thread_value_t) 1;
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
@@ -1085,25 +1095,23 @@
 
     tls = ngx_calloc(sizeof(ngx_core_tls_t), cycle->log);
     if (tls == NULL) {
-        return (void *) 1;
+        return (ngx_thread_value_t) 1;
     }
 
     err = ngx_thread_set_tls(ngx_core_tls_key, tls);
     if (err != 0) {
         ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
                       ngx_thread_set_tls_n " failed");
-        return (void *) 1;
+        return (ngx_thread_value_t) 1;
     }
 
-    if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
-        return (void *) 1;
-    }
+    ngx_mutex_lock(ngx_posted_events_mutex);
 
     for ( ;; ) {
         thr->state = NGX_THREAD_FREE;
 
         if (ngx_cond_wait(thr->cv, ngx_posted_events_mutex) == NGX_ERROR) {
-            return (void *) 1;
+            return (ngx_thread_value_t) 1;
         }
 
         if (ngx_terminate) {
@@ -1115,22 +1123,22 @@
                            "thread " NGX_TID_T_FMT " is done",
                            ngx_thread_self());
 
-            return (void *) 0;
+            return (ngx_thread_value_t) 0;
         }
 
         thr->state = NGX_THREAD_BUSY;
 
         if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
-            return (void *) 1;
+            return (ngx_thread_value_t) 1;
         }
 
         if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
-            return (void *) 1;
+            return (ngx_thread_value_t) 1;
         }
 
         if (ngx_process_changes) {
             if (ngx_process_changes(cycle, 1) == NGX_ERROR) {
-                return (void *) 1;
+                return (ngx_thread_value_t) 1;
             }
         }
     }
@@ -1185,7 +1193,7 @@
 
         ngx_add_timer(ev, 60 * 60 * 1000);
 
-        ngx_process_events(cycle);
+        ngx_process_events_and_timers(cycle);
     }
 }
 
diff --git a/src/os/unix/ngx_pthread_thread.c b/src/os/unix/ngx_pthread_thread.c
index 0b55c71..c91e65d 100644
--- a/src/os/unix/ngx_pthread_thread.c
+++ b/src/os/unix/ngx_pthread_thread.c
@@ -15,8 +15,9 @@
 static pthread_attr_t  thr_attr;
 
 
-ngx_err_t ngx_create_thread(ngx_tid_t *tid, void* (*func)(void *arg), void *arg,
-                            ngx_log_t *log)
+ngx_err_t
+ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (*func)(void *arg),
+    void *arg, ngx_log_t *log)
 {
     int  err;
 
@@ -42,7 +43,8 @@
 }
 
 
-ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
+ngx_int_t
+ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
 {   
     int  err;
 
@@ -70,7 +72,8 @@
 }
 
 
-ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
+ngx_mutex_t *
+ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
 {
     int           err;
     ngx_mutex_t  *m;
@@ -94,7 +97,8 @@
 }
 
 
-void ngx_mutex_destroy(ngx_mutex_t *m)
+void
+ngx_mutex_destroy(ngx_mutex_t *m)
 {
     int  err;
 
@@ -109,12 +113,13 @@
 }
 
 
-ngx_int_t ngx_mutex_lock(ngx_mutex_t *m)
+void
+ngx_mutex_lock(ngx_mutex_t *m)
 {
     int  err;
 
     if (!ngx_threaded) {
-        return NGX_OK;
+        return;
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "lock mutex %p", m);
@@ -124,16 +129,17 @@
     if (err != 0) {
         ngx_log_error(NGX_LOG_ALERT, m->log, err,
                       "pthread_mutex_lock(%p) failed", m);
-        return NGX_ERROR;
+        ngx_abort();
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);
 
-    return NGX_OK;
+    return;
 }
 
 
-ngx_int_t ngx_mutex_trylock(ngx_mutex_t *m)
+ngx_int_t
+ngx_mutex_trylock(ngx_mutex_t *m)
 {
     int  err;
 
@@ -152,7 +158,7 @@
     if (err != 0) {
         ngx_log_error(NGX_LOG_ALERT, m->log, err,
                       "pthread_mutex_trylock(%p) failed", m);
-        return NGX_ERROR;
+        ngx_abort();
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);
@@ -161,12 +167,13 @@
 }
 
 
-ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
+void
+ngx_mutex_unlock(ngx_mutex_t *m)
 {
     int  err;
 
     if (!ngx_threaded) {
-        return NGX_OK;
+        return;
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "unlock mutex %p", m);
@@ -176,16 +183,17 @@
     if (err != 0) {
         ngx_log_error(NGX_LOG_ALERT, m->log, err,
                       "pthread_mutex_unlock(%p) failed", m);
-        return NGX_ERROR;
+        ngx_abort();
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is unlocked", m);
 
-    return NGX_OK;
+    return;
 }
 
 
-ngx_cond_t *ngx_cond_init(ngx_log_t *log)
+ngx_cond_t *
+ngx_cond_init(ngx_log_t *log)
 {
     int          err;
     ngx_cond_t  *cv;
@@ -209,7 +217,8 @@
 }
 
 
-void ngx_cond_destroy(ngx_cond_t *cv)
+void
+ngx_cond_destroy(ngx_cond_t *cv)
 {
     int  err;
 
@@ -224,7 +233,8 @@
 }
 
 
-ngx_int_t ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m)
+ngx_int_t
+ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m)
 {
     int  err;
 
@@ -246,7 +256,8 @@
 }
 
 
-ngx_int_t ngx_cond_signal(ngx_cond_t *cv)
+ngx_int_t
+ngx_cond_signal(ngx_cond_t *cv)
 {
     int  err;
 
diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c
index 1219589..60885dd 100644
--- a/src/os/unix/ngx_socket.c
+++ b/src/os/unix/ngx_socket.c
@@ -13,7 +13,7 @@
  * while fcntl(F_SETFL, ~O_NONBLOCK) needs to learn before
  * the previous state using fcntl(F_GETFL).
  *
- * ioctl() and fcntl() are syscalls on at least FreeBSD 2.x, Linux 2.2
+ * ioctl() and fcntl() are syscalls at least in FreeBSD 2.x, Linux 2.2
  * and Solaris 7.
  *
  * ioctl() in Linux 2.4 and 2.6 uses BKL, however, fcntl(F_SETFL) uses it too.
@@ -73,6 +73,7 @@
 
 #elif (NGX_LINUX)
 
+
 int
 ngx_tcp_nopush(ngx_socket_t s)
 {
@@ -84,6 +85,7 @@
                       (const void *) &cork, sizeof(int));
 }
 
+
 int
 ngx_tcp_push(ngx_socket_t s)
 {
@@ -103,6 +105,7 @@
     return 0;
 }
 
+
 int
 ngx_tcp_push(ngx_socket_t s)
 {
diff --git a/src/os/unix/ngx_sunpro_atomic_sparc64.h b/src/os/unix/ngx_sunpro_atomic_sparc64.h
index e634416..6b4ce84 100644
--- a/src/os/unix/ngx_sunpro_atomic_sparc64.h
+++ b/src/os/unix/ngx_sunpro_atomic_sparc64.h
@@ -50,3 +50,9 @@
         old = res;
     }
 }
+
+
+#define ngx_memory_barrier()                                                  \
+        __asm (".volatile");                                                  \
+        __asm ("membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad");   \
+        __asm (".nonvolatile")
diff --git a/src/os/unix/ngx_thread.h b/src/os/unix/ngx_thread.h
index e630b35..5171be6 100644
--- a/src/os/unix/ngx_thread.h
+++ b/src/os/unix/ngx_thread.h
@@ -66,8 +66,8 @@
 
 
 ngx_int_t ngx_mutex_trylock(ngx_mutex_t *m);
-ngx_int_t ngx_mutex_lock(ngx_mutex_t *m);
-ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m);
+void ngx_mutex_lock(ngx_mutex_t *m);
+void ngx_mutex_unlock(ngx_mutex_t *m);
 
 #endif
 
@@ -90,10 +90,11 @@
 extern volatile ngx_thread_t  ngx_threads[NGX_MAX_THREADS];
 
 
-ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle);
-ngx_err_t ngx_create_thread(ngx_tid_t *tid, void* (*func)(void *arg), void *arg,
-                            ngx_log_t *log);
+typedef void *  ngx_thread_value_t;
 
+ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle);
+ngx_err_t ngx_create_thread(ngx_tid_t *tid,
+    ngx_thread_value_t (*func)(void *arg), void *arg, ngx_log_t *log);
 
 ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags);
 void ngx_mutex_destroy(ngx_mutex_t *m);
@@ -113,7 +114,7 @@
 #define NGX_TID_T_FMT         "%d"
 
 #define ngx_mutex_trylock(m)  NGX_OK
-#define ngx_mutex_lock(m)     NGX_OK
+#define ngx_mutex_lock(m)
 #define ngx_mutex_unlock(m)
 
 #define ngx_cond_signal(cv)
diff --git a/src/os/unix/ngx_time.c b/src/os/unix/ngx_time.c
index 1b1a566..927132d 100644
--- a/src/os/unix/ngx_time.c
+++ b/src/os/unix/ngx_time.c
@@ -8,20 +8,16 @@
 #include <ngx_core.h>
 
 
-void ngx_localtime(ngx_tm_t *tm)
+void
+ngx_localtime(time_t s, ngx_tm_t *tm)
 {
 #if (NGX_HAVE_LOCALTIME_R)
-    time_t     now;
-
-    now = ngx_time();
-    (void) localtime_r(&now, tm);
+    (void) localtime_r(&s, tm);
 
 #else
-    time_t     now;
     ngx_tm_t  *t;
 
-    now = ngx_time();
-    t = localtime(&now);
+    t = localtime(&s);
     *tm = *t;
 
 #endif
@@ -31,40 +27,32 @@
 }
 
 
-void ngx_libc_localtime(struct tm *tm)
+void
+ngx_libc_localtime(time_t s, struct tm *tm)
 {
 #if (NGX_HAVE_LOCALTIME_R)
-    time_t      now;
-
-    now = ngx_time();
-    (void) localtime_r(&now, tm);
+    (void) localtime_r(&s, tm);
 
 #else
-    time_t      now;
     struct tm  *t;
 
-    now = ngx_time();
-    t = localtime(&now);
+    t = localtime(&s);
     *tm = *t;
 
 #endif
 }
 
 
-void ngx_libc_gmtime(struct tm *tm)
+void
+ngx_libc_gmtime(time_t s, struct tm *tm)
 {
 #if (NGX_HAVE_LOCALTIME_R)
-    time_t      now;
-
-    now = ngx_time();
-    (void) gmtime_r(&now, tm);
+    (void) gmtime_r(&s, tm);
 
 #else
-    time_t      now;
     struct tm  *t;
 
-    now = ngx_time();
-    t = gmtime(&now);
+    t = gmtime(&s);
     *tm = *t;
 
 #endif
diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h
index f9fe3c5..b31bd47 100644
--- a/src/os/unix/ngx_time.h
+++ b/src/os/unix/ngx_time.h
@@ -52,9 +52,9 @@
 #endif
 
 
-void ngx_localtime(ngx_tm_t *tm);
-void ngx_libc_localtime(struct tm *tm);
-void ngx_libc_gmtime(struct tm *tm);
+void ngx_localtime(time_t s, ngx_tm_t *tm);
+void ngx_libc_localtime(time_t s, struct tm *tm);
+void ngx_libc_gmtime(time_t s, struct tm *tm);
 
 #define ngx_gettimeofday(tp)  (void) gettimeofday(tp, NULL);
 #define ngx_msleep(ms)        (void) usleep(ms * 1000)
diff --git a/src/os/win32/ngx_atomic.h b/src/os/win32/ngx_atomic.h
index 87de57d..1e33345 100644
--- a/src/os/win32/ngx_atomic.h
+++ b/src/os/win32/ngx_atomic.h
@@ -41,6 +41,9 @@
 #define ngx_atomic_fetch_add(p, add) InterlockedExchangeAdd((long *) p, add)
 
 
+#define ngx_memory_barrier()
+
+
 void ngx_spinlock(ngx_atomic_t *lock, ngx_uint_t spin);
 
 #define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c
index 7eabefe..be363e2 100644
--- a/src/os/win32/ngx_process_cycle.c
+++ b/src/os/win32/ngx_process_cycle.c
@@ -10,7 +10,7 @@
 #include <nginx.h>
 
 
-static void *ngx_worker_thread_cycle(void *data);
+static ngx_thread_value_t __stdcall ngx_worker_thread_cycle(void *data);
 static long __stdcall ngx_window_procedure(HWND window, u_int message,
     u_int wparam, long lparam);
 
@@ -202,7 +202,7 @@
 }
 
 
-static void *
+static ngx_thread_value_t __stdcall
 ngx_worker_thread_cycle(void *data)
 {
     ngx_cycle_t  *cycle;
@@ -212,10 +212,10 @@
     while (!ngx_quit) {
         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
 
-        ngx_process_events(cycle);
+        ngx_process_events_and_timers(cycle);
     }
 
-    return NULL;
+    return 0;
 }
 
 
diff --git a/src/os/win32/ngx_thread.c b/src/os/win32/ngx_thread.c
index 0703ac7..f8cedd2 100644
--- a/src/os/win32/ngx_thread.c
+++ b/src/os/win32/ngx_thread.c
@@ -14,13 +14,13 @@
 static size_t  stack_size;
 
 
-ngx_err_t ngx_create_thread(ngx_tid_t *tid, void* (*func)(void *arg), void *arg,
-                      ngx_log_t *log)
+ngx_err_t
+ngx_create_thread(ngx_tid_t *tid,
+    ngx_thread_value_t (__stdcall *func)(void *arg), void *arg, ngx_log_t *log)
 {
     ngx_err_t  err;
 
-    *tid = CreateThread(NULL, stack_size,
-                        (LPTHREAD_START_ROUTINE) func, arg, 0, NULL);
+    *tid = CreateThread(NULL, stack_size, func, arg, 0, NULL);
 
     if (*tid != NULL) {
         return 0;
@@ -32,7 +32,8 @@
 }
 
 
-ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
+ngx_int_t
+ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
 {
     stack_size = size;
 
@@ -40,7 +41,8 @@
 }
 
 
-ngx_err_t ngx_thread_key_create(ngx_tls_key_t *key)
+ngx_err_t
+ngx_thread_key_create(ngx_tls_key_t *key)
 {
     *key = TlsAlloc();
 
@@ -52,7 +54,8 @@
 }
 
 
-ngx_err_t ngx_thread_set_tls(ngx_tls_key_t *key, void *data)
+ngx_err_t
+ngx_thread_set_tls(ngx_tls_key_t *key, void *data)
 {
     if (TlsSetValue(*key, data) == 0) {
         return ngx_errno;
@@ -62,7 +65,8 @@
 }
 
 
-ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
+ngx_mutex_t *
+ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
 {
     return (ngx_mutex_t *) 1;
 }
@@ -70,15 +74,22 @@
 
 /* STUB */
 
-ngx_int_t
+void
 ngx_mutex_lock(ngx_mutex_t *m) {
-    return NGX_OK;
+    return;
 }
 
 
+
 ngx_int_t
 ngx_mutex_trylock(ngx_mutex_t *m) {
     return NGX_OK;
 }
 
+
+void
+ngx_mutex_unlock(ngx_mutex_t *m) {
+    return;
+}
+
 /**/
diff --git a/src/os/win32/ngx_thread.h b/src/os/win32/ngx_thread.h
index b55dcca..3da1dc2 100644
--- a/src/os/win32/ngx_thread.h
+++ b/src/os/win32/ngx_thread.h
@@ -14,6 +14,7 @@
 
 typedef HANDLE  ngx_tid_t;
 typedef DWORD   ngx_tls_key_t;
+typedef DWORD   ngx_thread_value_t;
 
 
 typedef struct {
@@ -22,8 +23,8 @@
 } ngx_mutex_t;
 
 
-ngx_err_t ngx_create_thread(ngx_tid_t *tid, void* (*func)(void *arg),
-    void *arg, ngx_log_t *log);
+ngx_err_t ngx_create_thread(ngx_tid_t *tid,
+    ngx_thread_value_t (__stdcall *func)(void *arg), void *arg, ngx_log_t *log);
 ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle);
 
 ngx_err_t ngx_thread_key_create(ngx_tls_key_t *key);
@@ -41,14 +42,13 @@
 
 ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags);
 
-ngx_int_t ngx_mutex_lock(ngx_mutex_t *m);
+void ngx_mutex_lock(ngx_mutex_t *m);
 ngx_int_t ngx_mutex_trylock(ngx_mutex_t *m);
+void ngx_mutex_unlock(ngx_mutex_t *m);
 
 
 /* STUB */
 #define NGX_MUTEX_LIGHT             0
-
-#define ngx_mutex_unlock(m)
 /**/
 
 
diff --git a/src/os/win32/ngx_time.c b/src/os/win32/ngx_time.c
index 04a1af6..39ce633 100644
--- a/src/os/win32/ngx_time.c
+++ b/src/os/win32/ngx_time.c
@@ -8,7 +8,8 @@
 #include <ngx_core.h>
 
 
-void ngx_gettimeofday(struct timeval *tp)
+void
+ngx_gettimeofday(struct timeval *tp)
 {
     uint64_t  intervals;
     FILETIME  ft;
@@ -36,29 +37,28 @@
 }
 
 
-void ngx_libc_localtime(struct tm *tm)
+void
+ngx_libc_localtime(time_t s, struct tm *tm)
 {
-    time_t      now;
     struct tm  *t;
 
-    now = ngx_time();
-    t = localtime(&now);
+    t = localtime(&s);
     *tm = *t;
 }
 
 
-void ngx_libc_gmtime(struct tm *tm)
+void
+ngx_libc_gmtime(time_t s, struct tm *tm)
 {
-    time_t      now;
     struct tm  *t;
 
-    now = ngx_time();
-    t = gmtime(&now);
+    t = gmtime(&s);
     *tm = *t;
 }
 
 
-ngx_int_t ngx_gettimezone(void)
+ngx_int_t
+ngx_gettimezone(void)
 {
     TIME_ZONE_INFORMATION  tz;
 
diff --git a/src/os/win32/ngx_time.h b/src/os/win32/ngx_time.h
index 4c14984..225c38c 100644
--- a/src/os/win32/ngx_time.h
+++ b/src/os/win32/ngx_time.h
@@ -40,8 +40,8 @@
 #define NGX_HAVE_GETTIMEZONE  1
 
 ngx_int_t ngx_gettimezone(void);
-void ngx_libc_localtime(struct tm *tm);
-void ngx_libc_gmtime(struct tm *tm);
+void ngx_libc_localtime(time_t s, struct tm *tm);
+void ngx_libc_gmtime(time_t s, struct tm *tm);
 void ngx_gettimeofday(struct timeval *tp);
 
 
diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h
index a814acb..9658c12 100644
--- a/src/os/win32/ngx_win32_config.h
+++ b/src/os/win32/ngx_win32_config.h
@@ -8,6 +8,10 @@
 #define _NGX_WIN32_CONFIG_H_INCLUDED_
 
 
+#define WIN32         0x0400
+#define _WIN32_WINNT  0x0400
+
+
 #define STRICT
 #define WIN32_LEAN_AND_MEAN