changeset 106:45f7329b4bd0 NGINX_0_3_0

nginx 0.3.0 *) Change: the 10-days live time limit of worker process was eliminated. The limit was introduced because of millisecond timers overflow.
author Igor Sysoev <http://sysoev.ru>
date Fri, 07 Oct 2005 00:00:00 +0400
parents 531d62c2a28d
children 495d867e35e8
files CHANGES CHANGES.ru auto/cc/gcc auto/cc/icc src/core/nginx.c src/core/nginx.h src/core/ngx_connection.h src/core/ngx_core.h src/core/ngx_rbtree.c src/core/ngx_rbtree.h src/core/ngx_string.c src/core/ngx_times.c src/core/ngx_times.h src/event/modules/ngx_devpoll_module.c src/event/modules/ngx_epoll_module.c src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_poll_module.c src/event/modules/ngx_rtsig_module.c src/event/modules/ngx_select_module.c src/event/ngx_event.h src/event/ngx_event_timer.c src/event/ngx_event_timer.h src/http/modules/ngx_http_autoindex_module.c src/http/modules/ngx_http_index_module.c src/http/modules/ngx_http_static_module.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_request.c src/http/ngx_http_variables.c src/os/unix/ngx_posix_init.c src/os/unix/ngx_process.c src/os/unix/ngx_process_cycle.c src/os/unix/ngx_process_cycle.h src/os/unix/ngx_time.h
diffstat 34 files changed, 407 insertions(+), 698 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+
+Changes with nginx 0.3.0                                         07 Oct 2005
+
+    *) Change: the 10-days live time limit of worker process was 
+       eliminated. The limit was introduced because of millisecond timers 
+       overflow.
+
 
 Changes with nginx 0.2.6                                         05 Oct 2005
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,3 +1,10 @@
+
+Изменения в nginx 0.3.0                                           07.10.2005
+
+    *) Изменение: убрано десятидневное ограничение времени работы рабочего 
+       процесса. Ограничение было введено из-за переполнения таймеров 
+       миллисекунд.
+
 
 Изменения в nginx 0.2.6                                           05.10.2005
 
--- a/auto/cc/gcc
+++ b/auto/cc/gcc
@@ -12,6 +12,8 @@ NGX_GCC_VER=`$CC -v 2>&1 | grep 'gcc ver
 
 echo " + gcc version: $NGX_GCC_VER"
 
+have=NGX_COMPILER value="\"gcc $NGX_GCC_VER\"" . auto/define
+
 
 # Solaris 7's /usr/ccs/bin/as does not support "-pipe"
 
--- a/auto/cc/icc
+++ b/auto/cc/icc
@@ -9,6 +9,8 @@ NGX_ICC_VER=`$CC -V 2>&1 | grep 'Version
 
 echo " + icc version: $NGX_ICC_VER"
 
+have=NGX_COMPILER value="\"Intel C Compiler $NGX_ICC_VER\"" . auto/define
+
 
 # optimizations
 
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -218,7 +218,7 @@ main(int argc, char *const *argv)
     if (cycle == NULL) {
         if (ngx_test_config) {
             ngx_log_error(NGX_LOG_EMERG, log, 0,
-                          "the configuration file \"%s\" test failed",
+                          "the configuration file %s test failed",
                           init_cycle.conf_file.data);
         }
 
@@ -227,7 +227,7 @@ main(int argc, char *const *argv)
 
     if (ngx_test_config) {
         ngx_log_error(NGX_LOG_INFO, log, 0,
-                      "the configuration file \"%s\" was tested successfully",
+                      "the configuration file %s was tested successfully",
                       cycle->conf_file.data);
         return 0;
     }
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.2.6"
+#define NGINX_VER          "nginx/0.3.0"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_OLDPID_EXT     ".oldbin"
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -39,7 +39,7 @@ struct ngx_listening_s {
     /* should be here because of the AcceptEx() preread */
     size_t              post_accept_buffer_size;
     /* should be here because of the deferred accept */
-    time_t              post_accept_timeout;
+    ngx_msec_t          post_accept_timeout;
 
     ngx_listening_t    *previous;
     ngx_connection_t   *connection;
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -36,6 +36,7 @@ typedef void (*ngx_connection_handler_pt
 
 
 #include <ngx_atomic.h>
+#include <ngx_rbtree.h>
 #include <ngx_time.h>
 #include <ngx_socket.h>
 #include <ngx_errno.h>
@@ -59,7 +60,6 @@ typedef void (*ngx_connection_handler_pt
 #if (NGX_PCRE)
 #include <ngx_regex.h>
 #endif
-#include <ngx_rbtree.h>
 #include <ngx_radix_tree.h>
 #include <ngx_times.h>
 #include <ngx_inet.h>
@@ -81,4 +81,7 @@ typedef void (*ngx_connection_handler_pt
 #define CRLF   "\x0d\x0a"
 
 
+#define ngx_abs(value)   (((value) >= 0) ? (value) : - (value))
+
+
 #endif /* _NGX_CORE_H_INCLUDED_ */
--- a/src/core/ngx_rbtree.c
+++ b/src/core/ngx_rbtree.c
@@ -47,7 +47,12 @@ ngx_rbtree_insert(ngx_rbtree_t **root, n
     temp = *root;
 
     for ( ;; ) {
-        if (node->key < temp->key) {
+
+        /*  node->key < temp->key */
+
+        if ((ngx_rbtree_key_int_t) node->key - (ngx_rbtree_key_int_t) temp->key
+            < 0)
+        {
             if (temp->left == sentinel) {
                 temp->left = node;
                 break;
--- a/src/core/ngx_rbtree.h
+++ b/src/core/ngx_rbtree.h
@@ -12,14 +12,18 @@
 #include <ngx_core.h>
 
 
+typedef ngx_uint_t  ngx_rbtree_key_t;
+typedef ngx_int_t   ngx_rbtree_key_int_t;
+
+
 typedef struct ngx_rbtree_s  ngx_rbtree_t;
 
 struct ngx_rbtree_s {
-   ngx_int_t       key;
-   ngx_rbtree_t   *left;
-   ngx_rbtree_t   *right;
-   ngx_rbtree_t   *parent;
-   char            color;
+    ngx_rbtree_key_t   key;
+    ngx_rbtree_t      *left;
+    ngx_rbtree_t      *right;
+    ngx_rbtree_t      *parent;
+    char               color;
 };
 
 
@@ -32,11 +36,11 @@ void ngx_rbtree_delete(ngx_rbtree_t **ro
 static ngx_inline ngx_rbtree_t *
 ngx_rbtree_min(ngx_rbtree_t *node, ngx_rbtree_t *sentinel)
 {
-   while (node->left != sentinel) {
-       node = node->left;
-   }
+    while (node->left != sentinel) {
+        node = node->left;
+    }
 
-   return node;
+    return node;
 }
 
 
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -57,6 +57,7 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t 
  *    %[0][width][u][x|X]L      int64_t/uint64_t
  *    %[0][width|m][u][x|X]A    ngx_atomic_int_t/ngx_atomic_uint_t
  *    %P                        ngx_pid_t
+ *    %M                        ngx_msec_t
  *    %r                        rlim_t
  *    %p                        pointer
  *    %V                        pointer to ngx_str_t
@@ -66,9 +67,6 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t 
  *    %c                        char
  *    %%                        %
  *
- *  TODO:
- *    %M                        ngx_msec_t
- *
  *  reserved:
  *    %t                        ptrdiff_t
  *    %S                        null-teminated wchar string
@@ -222,6 +220,11 @@ ngx_vsnprintf(u_char *buf, size_t max, c
                 sign = 1;
                 break;
 
+            case 'M':
+                ui64 = (uint64_t) va_arg(args, ngx_msec_t);
+                sign = 0;
+                break;
+
             case 'z':
                 if (sign) {
                     i64 = (int64_t) va_arg(args, ssize_t);
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -8,11 +8,9 @@
 #include <ngx_core.h>
 
 
-ngx_epoch_msec_t  ngx_elapsed_msec;
-ngx_epoch_msec_t  ngx_old_elapsed_msec;
-ngx_epoch_msec_t  ngx_start_msec;
+ngx_msec_t        ngx_current_time;
 
-ngx_int_t  ngx_gmtoff;
+ngx_int_t         ngx_gmtoff;
 
 static ngx_tm_t   ngx_cached_gmtime;
 
@@ -91,9 +89,7 @@ ngx_time_init(void)
 
     ngx_gettimeofday(&tv);
 
-    ngx_start_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
-    ngx_old_elapsed_msec = 0;
-    ngx_elapsed_msec = 0;
+    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
 #if !(NGX_WIN32)
     tzset();
--- a/src/core/ngx_times.h
+++ b/src/core/ngx_times.h
@@ -39,21 +39,13 @@ extern ngx_thread_volatile ngx_str_t  ng
 extern ngx_thread_volatile ngx_str_t  ngx_cached_http_time;
 extern ngx_thread_volatile ngx_str_t  ngx_cached_http_log_time;
 
-extern ngx_epoch_msec_t    ngx_start_msec;
+extern ngx_int_t   ngx_gmtoff;
 
 /*
- * msecs elapsed since ngx_start_msec in the current event cycle,
- * used in ngx_event_add_timer() and ngx_event_find_timer()
+ * milliseconds elapsed since epoch and truncated to ngx_msec_t,
+ * used in event timers
  */
-extern ngx_epoch_msec_t  ngx_elapsed_msec;
-
-/*
- * msecs elapsed since ngx_start_msec in the previous event cycle,
- * used in ngx_event_expire_timers()
- */
-extern ngx_epoch_msec_t  ngx_old_elapsed_msec;
-
-extern ngx_int_t         ngx_gmtoff;
+extern ngx_msec_t  ngx_current_time;
 
 
 #endif /* _NGX_TIMES_H_INCLUDED_ */
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -326,44 +326,23 @@ ngx_int_t
 ngx_devpoll_process_events(ngx_cycle_t *cycle)
 {
     int                 events, revents;
+    size_t              n;
+    ngx_err_t           err;
     ngx_int_t           i;
-    ngx_uint_t          lock, accept_lock, expire;
-    size_t              n;
-    ngx_msec_t          timer;
-    ngx_err_t           err;
+    ngx_uint_t          lock, accept_lock;
+    ngx_msec_t          timer, delta;
 #if 0
     ngx_cycle_t       **old_cycle;
 #endif
     ngx_event_t        *rev, *wev;
     ngx_connection_t   *c;
-    ngx_epoch_msec_t    delta;
     struct dvpoll       dvp;
     struct timeval      tv;
 
-    for ( ;; ) {
-        timer = ngx_event_find_timer();
-
-        if (timer != 0) {
-            break;
-        }
-
-        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "devpoll expired timer");
-
-        ngx_event_expire_timers((ngx_msec_t)
-                                    (ngx_elapsed_msec - ngx_old_elapsed_msec));
-    }
+    timer = ngx_event_find_timer();
 
     /* NGX_TIMER_INFINITE == INFTIM */
 
-    if (timer == NGX_TIMER_INFINITE) {
-        expire = 0;
-
-    } else {
-        expire = 1;
-    }
-
-    ngx_old_elapsed_msec = ngx_elapsed_msec;
     accept_lock = 0;
 
     if (ngx_accept_mutex) {
@@ -382,13 +361,12 @@ ngx_devpoll_process_events(ngx_cycle_t *
                        || timer > ngx_accept_mutex_delay)
             {
                 timer = ngx_accept_mutex_delay;
-                expire = 0;
             }
         }
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                   "devpoll timer: %d", timer);
+                   "devpoll timer: %M", timer);
 
     if (nchanges) {
         n = nchanges * sizeof(struct pollfd);
@@ -416,9 +394,8 @@ ngx_devpoll_process_events(ngx_cycle_t *
     ngx_gettimeofday(&tv);
     ngx_time_update(tv.tv_sec);
 
-    delta = ngx_elapsed_msec;
-    ngx_elapsed_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000
-                                          + tv.tv_usec / 1000 - ngx_start_msec;
+    delta = ngx_current_time;
+    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
     if (err) {
         ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
@@ -428,10 +405,10 @@ ngx_devpoll_process_events(ngx_cycle_t *
     }
 
     if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_elapsed_msec - delta;
+        delta = ngx_current_time - delta;
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "devpoll timer: %d, delta: %d", timer, (int) delta);
+                       "devpoll timer: %M, delta: %M", timer, delta);
     } else {
         if (events == 0) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
@@ -554,9 +531,7 @@ ngx_devpoll_process_events(ngx_cycle_t *
         ngx_mutex_unlock(ngx_posted_events_mutex);
     }
 
-    if (expire && delta) {
-        ngx_event_expire_timers((ngx_msec_t) delta);
-    }
+    ngx_event_expire_timers();
 
     if (!ngx_threaded) {
         ngx_event_process_posted(cycle);
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -387,56 +387,31 @@ ngx_epoll_process_events(ngx_cycle_t *cy
     int                events;
     uint32_t           revents;
     ngx_int_t          instance, i;
-    ngx_uint_t         lock, accept_lock, expire;
+    ngx_uint_t         lock, accept_lock;
     ngx_err_t          err;
     ngx_log_t         *log;
-    ngx_msec_t         timer;
+    ngx_msec_t         timer, delta;
     ngx_event_t       *rev, *wev;
     struct timeval     tv;
     ngx_connection_t  *c;
-    ngx_epoch_msec_t   delta;
 
-    for ( ;; ) { 
-        timer = ngx_event_find_timer();
+    timer = ngx_event_find_timer();
 
 #if (NGX_THREADS)
 
-        if (timer == NGX_TIMER_ERROR) {
-            return NGX_ERROR;
-        }
+    if (timer == NGX_TIMER_ERROR) {
+        return NGX_ERROR;
+    }
 
-        if (timer == NGX_TIMER_INFINITE || timer > 500) {
-            timer = 500;
-            break;
-        }
+    if (timer == NGX_TIMER_INFINITE || timer > 500) {
+        timer = 500;
+        break;
+    }
 
 #endif
 
-        if (timer != 0) {
-            break;
-        }
-
-        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "epoll expired timer");
-
-        ngx_event_expire_timers((ngx_msec_t)
-                                    (ngx_elapsed_msec - ngx_old_elapsed_msec));
-
-        if (ngx_posted_events && ngx_threaded) {
-            ngx_wakeup_worker_thread(cycle);
-        }
-    }
-
     /* NGX_TIMER_INFINITE == INFTIM */
 
-    if (timer == NGX_TIMER_INFINITE) {
-        expire = 0;
-
-    } else {
-        expire = 1;
-    }
-
-    ngx_old_elapsed_msec = ngx_elapsed_msec;
     accept_lock = 0;
 
     if (ngx_accept_mutex) {
@@ -455,13 +430,12 @@ ngx_epoll_process_events(ngx_cycle_t *cy
                        || timer > ngx_accept_mutex_delay)
             {
                 timer = ngx_accept_mutex_delay;
-                expire = 0;
             }
         }
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                   "epoll timer: %d", timer);
+                   "epoll timer: %M", timer);
 
     events = epoll_wait(ep, event_list, nevents, timer);
 
@@ -474,15 +448,14 @@ ngx_epoll_process_events(ngx_cycle_t *cy
     ngx_gettimeofday(&tv);
     ngx_time_update(tv.tv_sec);
 
-    delta = ngx_elapsed_msec;
-    ngx_elapsed_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000
-                                          + tv.tv_usec / 1000 - ngx_start_msec;
+    delta = ngx_current_time;
+    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
     if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_elapsed_msec - delta;
+        delta = ngx_current_time - delta;
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "epoll timer: %d, delta: %d", timer, (int) delta);
+                       "epoll timer: %M, delta: %M", timer, delta);
     } else {
         if (events == 0) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
@@ -645,9 +618,7 @@ ngx_epoll_process_events(ngx_cycle_t *cy
         ngx_mutex_unlock(ngx_posted_events_mutex);
     }
 
-    if (expire && delta) {
-        ngx_event_expire_timers((ngx_msec_t) delta);
-    }
+    ngx_event_expire_timers();
 
     if (ngx_posted_events) {
         if (ngx_threaded) {
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -445,47 +445,28 @@ ngx_kqueue_process_events(ngx_cycle_t *c
 {
     int                events, n;
     ngx_int_t          i, instance;
-    ngx_uint_t         lock, accept_lock, expire;
+    ngx_uint_t         lock, accept_lock;
     ngx_err_t          err;
-    ngx_msec_t         timer;
+    ngx_msec_t         timer, delta;
     ngx_event_t       *ev;
-    ngx_epoch_msec_t   delta;
     struct timeval     tv;
     struct timespec    ts, *tp;
 
-    for ( ;; ) {
-        timer = ngx_event_find_timer();
+    timer = ngx_event_find_timer();
 
 #if (NGX_THREADS)
 
-        if (timer == NGX_TIMER_ERROR) {
-            return NGX_ERROR;
-        }
+    if (timer == NGX_TIMER_ERROR) {
+        return NGX_ERROR;
+    }
 
-        if (timer == NGX_TIMER_INFINITE || timer > 500) {
-            timer = 500;
-            break;
-        }
+    if (timer == NGX_TIMER_INFINITE || timer > 500) {
+        timer = 500;
+        break;
+    }
 
 #endif
 
-        if (timer != 0) {
-            break;
-        }
-
-        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "kevent expired timer");
-
-        ngx_event_expire_timers((ngx_msec_t)
-                                    (ngx_elapsed_msec - ngx_old_elapsed_msec));
-
-        if (ngx_posted_events && ngx_threaded) {
-            ngx_wakeup_worker_thread(cycle);
-        }
-    }
-
-    ngx_old_elapsed_msec = ngx_elapsed_msec;
-    expire = 1;
     accept_lock = 0;
 
     if (ngx_accept_mutex) {
@@ -504,7 +485,6 @@ ngx_kqueue_process_events(ngx_cycle_t *c
                        || timer > ngx_accept_mutex_delay)
             {
                 timer = ngx_accept_mutex_delay;
-                expire = 0;
             }
         }
     }
@@ -524,7 +504,6 @@ ngx_kqueue_process_events(ngx_cycle_t *c
 
     if (timer == NGX_TIMER_INFINITE) {
         tp = NULL;
-        expire = 0;
 
     } else {
         ts.tv_sec = timer / 1000;
@@ -549,9 +528,8 @@ ngx_kqueue_process_events(ngx_cycle_t *c
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    "kevent events: %d", events);
 
-    delta = ngx_elapsed_msec;
-    ngx_elapsed_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000
-                                          + tv.tv_usec / 1000 - ngx_start_msec;
+    delta = ngx_current_time;
+    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
     if (err) {
         ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
@@ -561,10 +539,10 @@ ngx_kqueue_process_events(ngx_cycle_t *c
     }
 
     if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_elapsed_msec - delta;
+        delta = ngx_current_time - delta;
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "kevent timer: %d, delta: %d", timer, (int) delta);
+                       "kevent timer: %M, delta: %M", timer, delta);
 
     } else {
         if (events == 0) {
@@ -718,9 +696,7 @@ ngx_kqueue_process_events(ngx_cycle_t *c
         ngx_mutex_unlock(ngx_posted_events_mutex);
     }
 
-    if (expire && delta) {
-        ngx_event_expire_timers((ngx_msec_t) delta);
-    }
+    ngx_event_expire_timers();
 
     if (ngx_posted_events) {
         if (ngx_threaded) {
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -278,41 +278,19 @@ static ngx_int_t
 ngx_poll_process_events(ngx_cycle_t *cycle)
 {
     int                 ready, revents;
+    ngx_err_t           err;
     ngx_int_t           i, nready;
-    ngx_uint_t          n, found, lock, expire;
-    ngx_msec_t          timer;
-    ngx_err_t           err;
+    ngx_uint_t          n, found, lock;
+    ngx_msec_t          timer, delta;
     ngx_cycle_t       **old_cycle;
     ngx_event_t        *ev;
-    ngx_epoch_msec_t    delta;
     ngx_connection_t   *c;
     struct timeval      tv;
 
-    for ( ;; ) {
-        timer = ngx_event_find_timer();
-
-        if (timer != 0) {
-            break;
-        }
-
-        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "poll expired timer");
-
-        ngx_event_expire_timers((ngx_msec_t)
-                                (ngx_elapsed_msec - ngx_old_elapsed_msec));
-    }
+    timer = ngx_event_find_timer();
 
     /* NGX_TIMER_INFINITE == INFTIM */
 
-    if (timer == NGX_TIMER_INFINITE) {
-        expire = 0;
-
-    } else {
-        expire = 1;
-    }
-
-    ngx_old_elapsed_msec = ngx_elapsed_msec; 
-
 #if (NGX_DEBUG0)
     if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
         for (i = 0; i < nevents; i++) {
@@ -337,12 +315,11 @@ ngx_poll_process_events(ngx_cycle_t *cyc
                     || timer > ngx_accept_mutex_delay))
             { 
                 timer = ngx_accept_mutex_delay;
-                expire = 0;
             } 
         }
     }
 
-    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %d", timer);
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %M", timer);
 
     ready = poll(event_list, (u_int) nevents, (int) timer);
 
@@ -355,9 +332,8 @@ ngx_poll_process_events(ngx_cycle_t *cyc
     ngx_gettimeofday(&tv);
     ngx_time_update(tv.tv_sec);
 
-    delta = ngx_elapsed_msec;
-    ngx_elapsed_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000
-                                          + tv.tv_usec / 1000 - ngx_start_msec;
+    delta = ngx_current_time;
+    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    "poll ready %d of %d", ready, nevents);
@@ -370,10 +346,10 @@ ngx_poll_process_events(ngx_cycle_t *cyc
     }
 
     if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_elapsed_msec - delta;
+        delta = ngx_current_time - delta;
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "poll timer: %d, delta: %d", timer, (int) delta);
+                       "poll timer: %M, delta: %M", timer, delta);
     } else {
         if (ready == 0) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
@@ -593,9 +569,7 @@ ngx_poll_process_events(ngx_cycle_t *cyc
         ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events");
     }
 
-    if (expire && delta) {
-        ngx_event_expire_timers((ngx_msec_t) delta);
-    }
+    ngx_event_expire_timers();
 
     if (!ngx_threaded) {
         ngx_event_process_posted(cycle);
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -283,56 +283,35 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
 {
     int                 signo;
     ngx_int_t           instance;
-    ngx_uint_t          expire;
-    ngx_msec_t          timer;
+    ngx_msec_t          timer, delta;
     ngx_err_t           err;
     siginfo_t           si;
     ngx_event_t        *rev, *wev;
     struct timeval      tv;
     struct timespec     ts, *tp;
     struct sigaction    sa;
-    ngx_epoch_msec_t    delta;
     ngx_connection_t   *c;
     ngx_rtsig_conf_t   *rtscf;
 
     if (overflow) {
         timer = 0;
-        expire = 0;
 
     } else {
-        for ( ;; ) {
-            timer = ngx_event_find_timer();
+        timer = ngx_event_find_timer();
 
 #if (NGX_THREADS)
 
-            if (timer == NGX_TIMER_ERROR) {
-                return NGX_ERROR;
-            }
+        if (timer == NGX_TIMER_ERROR) {
+            return NGX_ERROR;
+        }
 
-            if (timer == NGX_TIMER_INFINITE || timer > 500) {
-                timer = 500;
-                break;
-            }
+        if (timer == NGX_TIMER_INFINITE || timer > 500) {
+            timer = 500;
+            break;
+        }
 
 #endif
 
-            if (timer != 0) {
-                break;
-            }
-
-            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                           "rtsig expired timer");
-
-            ngx_event_expire_timers((ngx_msec_t)
-                                    (ngx_elapsed_msec - ngx_old_elapsed_msec));
-
-            if (ngx_posted_events && ngx_threaded) {
-                ngx_wakeup_worker_thread(cycle);
-            }
-        }
-
-        expire = 1;
-
         if (ngx_accept_mutex) {
             if (ngx_accept_disabled > 0) {
                 ngx_accept_disabled--;
@@ -349,7 +328,6 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
                         || timer > ngx_accept_mutex_delay))
                 {
                     timer = ngx_accept_mutex_delay;
-                    expire = 0;
                 } 
             }
         }
@@ -357,7 +335,6 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
 
     if (timer == NGX_TIMER_INFINITE) {
         tp = NULL;
-        expire = 0;
 
     } else {
         ts.tv_sec = timer / 1000;
@@ -365,10 +342,8 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
         tp = &ts;
     }
 
-    ngx_old_elapsed_msec = ngx_elapsed_msec;
-
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                   "rtsig timer: %d", timer);
+                   "rtsig timer: %M", timer);
 
     /* Linux's sigwaitinfo() is sigtimedwait() with the NULL timeout pointer */
 
@@ -402,9 +377,8 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
     ngx_gettimeofday(&tv);
     ngx_time_update(tv.tv_sec);
 
-    delta = ngx_elapsed_msec;
-    ngx_elapsed_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000
-                                          + tv.tv_usec / 1000 - ngx_start_msec;
+    delta = ngx_current_time;
+    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
     if (err) {
         ngx_accept_mutex_unlock();
@@ -414,10 +388,10 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
     }
 
     if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_elapsed_msec - delta;
+        delta = ngx_current_time - delta;
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "rtsig timer: %d, delta: %d", timer, (int) delta);
+                       "rtsig timer: %M, delta: %M", timer, delta);
     }
 
     rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
@@ -557,9 +531,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
 
     ngx_accept_mutex_unlock();
 
-    if (expire && delta) {
-        ngx_event_expire_timers((ngx_msec_t) delta);
-    }
+    ngx_event_expire_timers();
 
     if (ngx_posted_events) {
         if (ngx_threaded) {
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -265,34 +265,17 @@ static ngx_int_t
 ngx_select_process_events(ngx_cycle_t *cycle)
 {
     int                       ready, nready;
-    ngx_uint_t                i, found, lock, expire;
+    ngx_uint_t                i, found, lock;
     ngx_err_t                 err;
-    ngx_msec_t                timer;
+    ngx_msec_t                timer, delta;
     ngx_event_t              *ev;
     ngx_connection_t         *c;
-    ngx_epoch_msec_t          delta;
     struct timeval            tv, *tp;
 #if (NGX_HAVE_SELECT_CHANGE_TIMEOUT)
-    static ngx_epoch_msec_t   deltas = 0;
+    static ngx_msec_t         deltas = 0;
 #endif
 
-    for ( ;; ) {
-        timer = ngx_event_find_timer();
-
-        if (timer != 0) {
-            break;
-        }
-
-        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "select expired timer");
-
-        ngx_event_expire_timers((ngx_msec_t)
-                                    (ngx_elapsed_msec - ngx_old_elapsed_msec));
-    }
-
-    ngx_old_elapsed_msec = ngx_elapsed_msec;
-
-    expire = 1;
+    timer = ngx_event_find_timer();
 
 #if !(NGX_WIN32)
 
@@ -310,7 +293,6 @@ ngx_select_process_events(ngx_cycle_t *c
                     || timer > ngx_accept_mutex_delay))
             {
                 timer = ngx_accept_mutex_delay;
-                expire = 0;
             }
         }
     }
@@ -347,16 +329,15 @@ ngx_select_process_events(ngx_cycle_t *c
 
     if (timer == NGX_TIMER_INFINITE) {
         tp = NULL;
-        expire = 0;
 
     } else {
-        tv.tv_sec = timer / 1000;
-        tv.tv_usec = (timer % 1000) * 1000;
+        tv.tv_sec = (long) (timer / 1000);
+        tv.tv_usec = (long) ((timer % 1000) * 1000);
         tp = &tv;
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                   "select timer: %d", timer);
+                   "select timer: %M", timer);
 
     work_read_fd_set = master_read_fd_set;
     work_write_fd_set = master_write_fd_set;
@@ -386,7 +367,7 @@ ngx_select_process_events(ngx_cycle_t *c
 #if (NGX_HAVE_SELECT_CHANGE_TIMEOUT)
 
     if (timer != NGX_TIMER_INFINITE) {
-        delta = timer - (tv.tv_sec * 1000 + tv.tv_usec / 1000);
+        delta = timer - ((ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000);
 
         /*
          * learn the real time and update the cached time
@@ -399,22 +380,23 @@ ngx_select_process_events(ngx_cycle_t *c
             ngx_time_update(tv.tv_sec);
             deltas = tv.tv_usec / 1000;
 
-            ngx_elapsed_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000
-                                          + tv.tv_usec / 1000 - ngx_start_msec;
+            ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000
+                                                           + tv.tv_usec / 1000;
         } else {
-            ngx_elapsed_msec += delta;
+            ngx_current_time += delta;
         }
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "select timer: %d, delta: %d", timer, (int) delta);
+                       "select timer: %M, delta: %M", timer, delta);
 
     } else {
-        delta = 0;
+        deltas = 0;
+
         ngx_gettimeofday(&tv);
         ngx_time_update(tv.tv_sec);
 
-        ngx_elapsed_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000
-                                          + tv.tv_usec / 1000 - ngx_start_msec;
+        delta = ngx_current_time;
+        ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
         if (ready == 0) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
@@ -429,15 +411,14 @@ ngx_select_process_events(ngx_cycle_t *c
     ngx_gettimeofday(&tv);
     ngx_time_update(tv.tv_sec);
 
-    delta = ngx_elapsed_msec;
-    ngx_elapsed_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000
-                                          + tv.tv_usec / 1000 - ngx_start_msec;
+    delta = ngx_current_time;
+    ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
     if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_elapsed_msec - delta;
+        delta = ngx_current_time - delta;
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "select timer: %d, delta: %d", timer, (int) delta);
+                       "select timer: %M, delta: %M", timer, delta);
 
     } else {
         if (ready == 0) {
@@ -594,9 +575,7 @@ ngx_select_process_events(ngx_cycle_t *c
         ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select ready != events");
     }
 
-    if (expire && delta) {
-        ngx_event_expire_timers((ngx_msec_t) delta);
-    }
+    ngx_event_expire_timers();
 
     if (!ngx_threaded) {
         ngx_event_process_posted(cycle);
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -136,11 +136,11 @@ struct ngx_event_s {
      * STUB: The inline of "ngx_rbtree_t  rbtree;"
      */
 
-    ngx_int_t        rbtree_key;
-    void            *rbtree_left;
-    void            *rbtree_right;
-    void            *rbtree_parent;
-    char             rbtree_color;
+    ngx_rbtree_key_t   rbtree_key;
+    void              *rbtree_left;
+    void              *rbtree_right;
+    void              *rbtree_parent;
+    char               rbtree_color;
 
 
     unsigned         closed:1;
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -60,28 +60,18 @@ ngx_event_find_timer(void)
 
     ngx_mutex_unlock(ngx_event_timer_mutex);
 
-    timer = (ngx_msec_t)
-         (node->key * NGX_TIMER_RESOLUTION -
-               ngx_elapsed_msec / NGX_TIMER_RESOLUTION * NGX_TIMER_RESOLUTION);
-#if 0
-                         (node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec);
-#endif
+    timer = (ngx_msec_t) node->key - ngx_current_time;
 
     return timer > 0 ? timer : 0 ;
 }
 
 
 void
-ngx_event_expire_timers(ngx_msec_t timer)
+ngx_event_expire_timers(void)
 {
     ngx_event_t   *ev;
     ngx_rbtree_t  *node;
 
-    if (timer < 0) {
-        /* avoid the endless loop if the time goes backward for some reason */
-        timer = 0;
-    }
-
     for ( ;; ) {
 
         if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
@@ -95,8 +85,11 @@ ngx_event_expire_timers(ngx_msec_t timer
         node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
                               &ngx_event_timer_sentinel);
 
-        if (node->key <= (ngx_msec_t)
-                         (ngx_old_elapsed_msec + timer) / NGX_TIMER_RESOLUTION)
+        /* node->key <= ngx_current_time */
+
+        if ((ngx_rbtree_key_int_t) node->key
+                                      - (ngx_rbtree_key_int_t) ngx_current_time
+            <= 0)
         {
             ev = (ngx_event_t *)
                            ((char *) node - offsetof(ngx_event_t, rbtree_key));
@@ -120,7 +113,7 @@ ngx_event_expire_timers(ngx_msec_t timer
 #endif
 
             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
-                           "event timer del: %d: %i",
+                           "event timer del: %d: %M",
                            ngx_event_ident(ev->data), ev->rbtree_key);
 
             ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree,
--- a/src/event/ngx_event_timer.h
+++ b/src/event/ngx_event_timer.h
@@ -16,24 +16,12 @@
 #define NGX_TIMER_INFINITE  (ngx_msec_t) -1
 #define NGX_TIMER_ERROR     (ngx_msec_t) -2
 
-
-/*
- * the 32-bit timer key value resolution
- *
- * 1 msec - 24 days
- * 10 msec - 8 months
- * 50 msec - 3 years 5 months
- * 100 msec - 6 years 10 months
- */
-
-#define NGX_TIMER_RESOLUTION  1
-
 #define NGX_TIMER_LAZY_DELAY  300
 
 
 ngx_int_t ngx_event_timer_init(ngx_log_t *log);
 ngx_msec_t ngx_event_find_timer(void);
-void ngx_event_expire_timers(ngx_msec_t timer);
+void ngx_event_expire_timers(void);
 
 
 #if (NGX_THREADS)
@@ -49,7 +37,7 @@ static ngx_inline void
 ngx_event_del_timer(ngx_event_t *ev)
 {
     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
-                   "event timer del: %d: %d",
+                   "event timer del: %d: %M",
                     ngx_event_ident(ev->data), ev->rbtree_key);
 
     if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
@@ -75,14 +63,10 @@ ngx_event_del_timer(ngx_event_t *ev)
 static ngx_inline void
 ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
 {
-    ngx_int_t  key;
+    ngx_rbtree_key_t      key;
+    ngx_rbtree_key_int_t  diff;
 
-    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
+    key = ngx_current_time + timer;
 
     if (ev->timer_set) {
 
@@ -92,11 +76,11 @@ ngx_event_add_timer(ngx_event_t *ev, ngx
          * the rbtree operations for the fast connections.
          */
 
-        if (abs(key - ev->rbtree_key)
-                                 < NGX_TIMER_LAZY_DELAY / NGX_TIMER_RESOLUTION)
-        {
+        diff = (ngx_rbtree_key_int_t) (key - ev->rbtree_key);
+
+        if (ngx_abs(diff) < NGX_TIMER_LAZY_DELAY) {
             ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
-                           "event timer: %d, old: %i, new: %i",
+                           "event timer: %d, old: %M, new: %M",
                             ngx_event_ident(ev->data), ev->rbtree_key, key);
             return;
         }
@@ -106,9 +90,9 @@ ngx_event_add_timer(ngx_event_t *ev, ngx
 
     ev->rbtree_key = key;
 
-    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
-                   "event timer add: %d: %i",
-                    ngx_event_ident(ev->data), ev->rbtree_key);
+    ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+                   "event timer add: %d: %M:%M",
+                    ngx_event_ident(ev->data), timer, ev->rbtree_key);
 
     if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
         return;
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -39,13 +39,15 @@ typedef struct {
 } ngx_http_autoindex_loc_conf_t;
 
 
-#define NGX_HTTP_AUTOINDEX_NAME_LEN  50
+#define NGX_HTTP_AUTOINDEX_PREALLOCATE  50
+
+#define NGX_HTTP_AUTOINDEX_NAME_LEN     50
 
 
 static int ngx_libc_cdecl ngx_http_autoindex_cmp_entries(const void *one,
     const void *two);
 static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r,
-    ngx_dir_t *dir, u_char *name);
+    ngx_dir_t *dir, ngx_str_t *name);
 static ngx_int_t ngx_http_autoindex_init(ngx_cycle_t *cycle);
 static void *ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf);
 static char *ngx_http_autoindex_merge_loc_conf(ngx_conf_t *cf,
@@ -131,20 +133,19 @@ static u_char tail[] =
 static ngx_int_t
 ngx_http_autoindex_handler(ngx_http_request_t *r)
 {
-    u_char                         *last, scale;
+    u_char                         *last, *filename, scale;
     off_t                           length;
-    size_t                          len, copy;
+    size_t                          len, copy, allocated;
     ngx_tm_t                        tm;
-    ngx_int_t                       rc, size;
-    ngx_uint_t                      i, level;
     ngx_err_t                       err;
     ngx_buf_t                      *b;
-    ngx_chain_t                     out;
-    ngx_str_t                       dname, fname;
+    ngx_int_t                       rc, size;
+    ngx_str_t                       path;
     ngx_dir_t                       dir;
+    ngx_uint_t                      i, level;
     ngx_pool_t                     *pool;
+    ngx_chain_t                     out;
     ngx_array_t                     entries;
-    ngx_http_core_loc_conf_t       *clcf;
     ngx_http_autoindex_entry_t     *entry;
     ngx_http_autoindex_loc_conf_t  *alcf;
 
@@ -166,41 +167,21 @@ ngx_http_autoindex_handler(ngx_http_requ
         return NGX_DECLINED;
     }
 
-    /* TODO: pool should be temporary pool */
-    pool = r->pool;
-
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+    /* NGX_DIR_MASK_LEN is lesser than NGX_HTTP_AUTOINDEX_PREALLOCATE */
 
-    if (clcf->alias) {
-        dname.data = ngx_palloc(pool, clcf->root.len + r->uri.len
-                                                     + NGX_DIR_MASK_LEN + 1
-                                                     - clcf->name.len);
-        if (dname.data == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-    
-        last = ngx_cpymem(dname.data, clcf->root.data, clcf->root.len);
-        last = ngx_cpystrn(last, r->uri.data + clcf->name.len,
-                           r->uri.len - clcf->name.len + 1);
-
-    } else {
-        dname.data = ngx_palloc(pool, clcf->root.len + r->uri.len
-                                                     + NGX_DIR_MASK_LEN);
-        if (dname.data == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        last = ngx_cpymem(dname.data, clcf->root.data, clcf->root.len);
-        last = ngx_cpystrn(last, r->uri.data, r->uri.len);
+    last = ngx_http_map_uri_to_path(r, &path, NGX_HTTP_AUTOINDEX_PREALLOCATE);
+    if (last == NULL) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    dname.len = last - dname.data;
+    allocated = path.len;
+    path.len = last - path.data - 1;
+    path.data[path.len] = '\0';
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http autoindex: \"%s\"", dname.data);
+                   "http autoindex: \"%s\"", path.data);
 
-
-    if (ngx_open_dir(&dname, &dir) == NGX_ERROR) {
+    if (ngx_open_dir(&path, &dir) == NGX_ERROR) {
         err = ngx_errno;
 
         if (err == NGX_ENOENT
@@ -220,20 +201,25 @@ ngx_http_autoindex_handler(ngx_http_requ
         }
 
         ngx_log_error(level, r->connection->log, err,
-                      ngx_open_dir_n " \"%s\" failed", dname.data);
+                      ngx_open_dir_n " \"%s\" failed", path.data);
 
         return rc;
     }
 
 #if (NGX_SUPPRESS_WARN)
+
     /* MSVC thinks 'entries' may be used without having been initialized */
     ngx_memzero(&entries, sizeof(ngx_array_t));
+
 #endif
 
-    if (ngx_array_init(&entries, pool, 50, sizeof(ngx_http_autoindex_entry_t))
-        == NGX_ERROR)
+    /* TODO: pool should be temporary pool */
+    pool = r->pool;
+
+    if (ngx_array_init(&entries, pool, 40, sizeof(ngx_http_autoindex_entry_t))
+        != NGX_OK)
     {
-        return ngx_http_autoindex_error(r, &dir, dname.data);
+        return ngx_http_autoindex_error(r, &dir, &path);
     }
 
     r->headers_out.status = NGX_HTTP_OK;
@@ -246,10 +232,8 @@ ngx_http_autoindex_handler(ngx_http_requ
         return rc;
     }
 
-    fname.len = 0;
-#if (NGX_SUPPRESS_WARN)
-    fname.data = NULL;
-#endif
+    filename = path.data;
+    filename[path.len] = '/';
 
     for ( ;; ) {
         ngx_set_errno(0);
@@ -259,8 +243,8 @@ ngx_http_autoindex_handler(ngx_http_requ
 
             if (err != NGX_ENOMOREFILES) {
                 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
-                              ngx_read_dir_n " \"%s\" failed", dname.data);
-                return ngx_http_autoindex_error(r, &dir, dname.data);
+                              ngx_read_dir_n " \"%V\" failed", &path);
+                return ngx_http_autoindex_error(r, &dir, &path);
             }
 
             break; 
@@ -277,49 +261,51 @@ ngx_http_autoindex_handler(ngx_http_requ
 
         if (!dir.valid_info) {
 
-            if (dname.len + 1 + len + 1 > fname.len) {
-                fname.len = dname.len + 1 + len + 1 + 32;
+            /* 1 byte for '/' and 1 byte for terminating '\0' */
 
-                fname.data = ngx_palloc(pool, fname.len);
-                if (fname.data == NULL) {
-                    return ngx_http_autoindex_error(r, &dir, dname.data);
+            if (path.len + 1 + len + 1 > allocated) {
+                allocated = path.len + 1 + len + 1
+                                     + NGX_HTTP_AUTOINDEX_PREALLOCATE;
+
+                filename = ngx_palloc(pool, allocated);
+                if (filename == NULL) {
+                    return ngx_http_autoindex_error(r, &dir, &path);
                 }
 
-                last = ngx_cpystrn(fname.data, dname.data,
-                                   dname.len + 1);
+                last = ngx_cpystrn(filename, path.data, path.len + 1);
                 *last++ = '/';
             }
 
             ngx_cpystrn(last, ngx_de_name(&dir), len + 1);
 
-            if (ngx_de_info(fname.data, &dir) == NGX_FILE_ERROR) {
+            if (ngx_de_info(filename, &dir) == NGX_FILE_ERROR) {
                 err = ngx_errno;
 
                 if (err != NGX_ENOENT) {
                     ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
-                                  ngx_de_info_n " \"%s\" failed", fname.data);
-                    return ngx_http_autoindex_error(r, &dir, dname.data);
+                                  ngx_de_info_n " \"%s\" failed", filename);
+                    return ngx_http_autoindex_error(r, &dir, &path);
                 }
 
-                if (ngx_de_link_info(fname.data, &dir) == NGX_FILE_ERROR) {
+                if (ngx_de_link_info(filename, &dir) == NGX_FILE_ERROR) {
                     ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
                                   ngx_de_link_info_n " \"%s\" failed",
-                                  fname.data);
-                    return ngx_http_autoindex_error(r, &dir, dname.data);
+                                  filename);
+                    return ngx_http_autoindex_error(r, &dir, &path);
                 }
             }
         }
 
         entry = ngx_array_push(&entries);
         if (entry == NULL) {
-            return ngx_http_autoindex_error(r, &dir, dname.data);
+            return ngx_http_autoindex_error(r, &dir, &path);
         }
 
         entry->name.len = len;        
 
         entry->name.data = ngx_palloc(pool, len + 1);
         if (entry->name.data == NULL) {
-            return ngx_http_autoindex_error(r, &dir, dname.data);
+            return ngx_http_autoindex_error(r, &dir, &path);
         }
 
         ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1);
@@ -340,7 +326,7 @@ ngx_http_autoindex_handler(ngx_http_requ
 
     if (ngx_close_dir(&dir) == NGX_ERROR) {
         ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
-                      ngx_close_dir_n " \"%s\" failed", dname.data);
+                      ngx_close_dir_n " \"%s\" failed", &path);
     }
 
     len = sizeof(title) - 1
@@ -586,11 +572,11 @@ ngx_http_autoindex_alloc(ngx_http_autoin
 
 
 static ngx_int_t
-ngx_http_autoindex_error(ngx_http_request_t *r, ngx_dir_t *dir, u_char *name)
+ngx_http_autoindex_error(ngx_http_request_t *r, ngx_dir_t *dir, ngx_str_t *name)
 {
     if (ngx_close_dir(dir) == NGX_ERROR) {
         ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
-                      ngx_close_dir_n " \"%s\" failed", name);
+                      ngx_close_dir_n " \"%V\" failed", name);
     }
 
     return NGX_HTTP_INTERNAL_SERVER_ERROR;
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -24,10 +24,8 @@ typedef struct {
 
 typedef struct {
     ngx_uint_t               current;
-    size_t                   allocated;
 
-    u_char                  *path;
-    ngx_str_t                uri;
+    ngx_str_t                path;
     ngx_str_t                index;
 
     ngx_uint_t               tested;     /* unsigned  tested:1 */
@@ -37,8 +35,6 @@ typedef struct {
 #define NGX_HTTP_DEFAULT_INDEX   "index.html"
 
 
-static ngx_int_t ngx_http_index_alloc(ngx_http_request_t *r, size_t size,
-    ngx_http_index_ctx_t *ctx, ngx_http_core_loc_conf_t *clcf);
 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
     ngx_http_index_ctx_t *ctx);
 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
@@ -120,11 +116,12 @@ ngx_module_t  ngx_http_index_module = {
 static ngx_int_t
 ngx_http_index_handler(ngx_http_request_t *r)
 {
-    u_char                       *name;
+    u_char                       *last;
     size_t                        len;
     ngx_fd_t                      fd;
     ngx_int_t                     rc;
     ngx_err_t                     err;
+    ngx_str_t                     uri;
     ngx_log_t                    *log;
     ngx_uint_t                    i;
     ngx_http_index_t             *index;
@@ -152,7 +149,6 @@ ngx_http_index_handler(ngx_http_request_
      * and may be called several times
      */
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
     ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
@@ -184,7 +180,9 @@ ngx_http_index_handler(ngx_http_request_
             e.ip = index[i].lengths->elts;
             e.request = r;
 
-            len = 1;
+            /* 1 byte for terminating '\0' and 4 bytes is preallocation */
+
+            len = 1 + 4;
 
             while (*(uintptr_t *) e.ip) {
                 lcode = *(ngx_http_script_len_code_pt *) e.ip;
@@ -194,14 +192,21 @@ ngx_http_index_handler(ngx_http_request_
             ctx->index.len = len;
         }
 
-        if (len > ctx->allocated) {
-            if (ngx_http_index_alloc(r, len, ctx, clcf) != NGX_OK) {
-                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        if (len > ctx->path.len) {
+
+            last = ngx_http_map_uri_to_path(r, &ctx->path, len);
+            if (last == NULL) {
+                return NGX_ERROR;
             }
+
+            ctx->index.data = last;
         }
 
         if (index[i].values == NULL) {
-            ngx_memcpy(ctx->index.data, index[i].name.data, ctx->index.len);
+
+            /* index[i].name.len includes the terminating '\0' */
+
+            ngx_memcpy(ctx->index.data, index[i].name.data, index[i].name.len);
 
         } else {
             e.ip = index[i].values->elts;
@@ -220,12 +225,10 @@ ngx_http_index_handler(ngx_http_request_
             *e.pos++ = '\0';
         }
 
-        name = ctx->path;
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
+                       "open index \"%s\"", ctx->path.data);
 
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
-                       "open index \"%s\"", name);
-
-        fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);
+        fd = ngx_open_file(ctx->path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
 
         if (fd == (ngx_fd_t) NGX_AGAIN) {
             ctx->current = i;
@@ -236,7 +239,7 @@ ngx_http_index_handler(ngx_http_request_
             err = ngx_errno;
 
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, err,
-                           ngx_open_file_n " \"%s\" failed", name);
+                           ngx_open_file_n " \"%s\" failed", ctx->path.data);
 
             if (err == NGX_ENOTDIR) {
                 return ngx_http_index_error(r, ctx, err);
@@ -260,7 +263,7 @@ ngx_http_index_handler(ngx_http_request_
             }
 
             ngx_log_error(NGX_LOG_ERR, log, err,
-                          ngx_open_file_n " \"%s\" failed", name);
+                          ngx_open_file_n " \"%s\" failed", ctx->path.data);
 
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
@@ -272,22 +275,31 @@ ngx_http_index_handler(ngx_http_request_
         }
 
         cln->fd = fd;
-        cln->name = name;
+        cln->name = ctx->path.data;
         cln->log = r->pool->log;
 
         if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
-        if (clcf->alias) {
-            name = ngx_cpymem(ctx->uri.data, r->uri.data, r->uri.len);
-            ngx_memcpy(name, ctx->index.data, ctx->index.len - 1);
+        uri.len = r->uri.len + ctx->index.len - 1;
+
+        if (!clcf->alias) {
+            uri.data = ctx->path.data + clcf->root.len;
+
+        } else {
+            uri.data = ngx_palloc(r->pool, uri.len);
+            if (uri.data == NULL) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            last = ngx_cpymem(uri.data, r->uri.data, r->uri.len);
+            ngx_memcpy(last, ctx->index.data, ctx->index.len - 1);
         }
 
-        ctx->uri.len = r->uri.len + ctx->index.len - 1;
-
-        return ngx_http_internal_redirect(r, &ctx->uri, &r->args);
+        return ngx_http_internal_redirect(r, &uri, &r->args);
     }
 
     return NGX_DECLINED;
@@ -295,45 +307,6 @@ ngx_http_index_handler(ngx_http_request_
 
 
 static ngx_int_t
-ngx_http_index_alloc(ngx_http_request_t *r, size_t size,
-    ngx_http_index_ctx_t *ctx, ngx_http_core_loc_conf_t *clcf)
-{
-    ctx->allocated = size;
-
-    if (!clcf->alias) {
-        ctx->path = ngx_palloc(r->pool, clcf->root.len + r->uri.len + size);
-        if (ctx->path == NULL) {
-            return NGX_ERROR;
-        }
-
-        ctx->uri.data = ngx_cpymem(ctx->path, clcf->root.data, clcf->root.len);
-
-        ctx->index.data = ngx_cpymem(ctx->uri.data, r->uri.data, r->uri.len);
-
-    } else {
-        ctx->path = ngx_palloc(r->pool,
-                          clcf->root.len + r->uri.len - clcf->name.len + size);
-        if (ctx->path == NULL) {
-            return NGX_ERROR;
-        }
-
-        ctx->uri.data = ngx_palloc(r->pool, r->uri.len + size);
-        if (ctx->uri.data == NULL) {
-            return NGX_ERROR;
-        }
-
-        ngx_memcpy(ctx->path, clcf->root.data, clcf->root.len);
-
-        ctx->index.data = ngx_cpymem(ctx->path + clcf->root.len,
-                                     r->uri.data + clcf->name.len,
-                                     r->uri.len - clcf->name.len);
-    }
-
-    return NGX_OK;
-}
-
-
-static ngx_int_t
 ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx)
 {
     ngx_err_t        err;
@@ -342,9 +315,9 @@ ngx_http_index_test_dir(ngx_http_request
     *(ctx->index.data - 1) = '\0';
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http index check dir: \"%s\"", ctx->path);
+                   "http index check dir: \"%s\"", ctx->path.data);
 
-    if (ngx_file_info(ctx->path, &fi) == -1) {
+    if (ngx_file_info(ctx->path.data, &fi) == -1) {
 
         err = ngx_errno;
 
@@ -354,7 +327,7 @@ ngx_http_index_test_dir(ngx_http_request
         }
 
         ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
-                      ngx_file_info_n " \"%s\" failed", ctx->path);
+                      ngx_file_info_n " \"%s\" failed", ctx->path.data);
 
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -366,7 +339,7 @@ ngx_http_index_test_dir(ngx_http_request
     }
 
     ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                  "\"%s\" is not a directory", ctx->path);
+                  "\"%s\" is not a directory", ctx->path.data);
 
     return NGX_HTTP_INTERNAL_SERVER_ERROR;
 }
@@ -378,13 +351,13 @@ ngx_http_index_error(ngx_http_request_t 
 {
     if (err == NGX_EACCES) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
-                      "\"%s\" is forbidden", ctx->path);
+                      "\"%s\" is forbidden", ctx->path.data);
     
         return NGX_HTTP_FORBIDDEN;
     }
 
     ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
-                  "\"%s\" is not found", ctx->path);
+                  "\"%s\" is not found", ctx->path.data);
 
     return NGX_HTTP_NOT_FOUND;
 }
@@ -494,14 +467,15 @@ ngx_http_index_set_index(ngx_conf_t *cf,
         n = ngx_http_script_variables_count(&value[i]);
 
         if (n == 0) {
-            index->name.len++;
-
             if (ilcf->max_index_len != 0
                 && ilcf->max_index_len < index->name.len)
             {
                 ilcf->max_index_len = index->name.len;
             }
 
+            /* include the terminating '\0' to the length to use ngx_memcpy() */
+            index->name.len++;
+
             continue;
         }
 
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -72,18 +72,18 @@ ngx_module_t  ngx_http_static_module = {
 static ngx_int_t
 ngx_http_static_handler(ngx_http_request_t *r)
 {
-    u_char                      *last;
-    ngx_fd_t                     fd;
-    ngx_int_t                    rc;
-    ngx_uint_t                   level;
-    ngx_str_t                    name, location;
-    ngx_err_t                    err;
-    ngx_log_t                   *log;
-    ngx_buf_t                   *b;
-    ngx_chain_t                  out;
-    ngx_file_info_t              fi;
-    ngx_pool_cleanup_file_t     *cln;
-    ngx_http_core_loc_conf_t    *clcf;
+    u_char                    *last, *location;
+    ngx_fd_t                   fd;
+    ngx_int_t                  rc;
+    ngx_uint_t                 level;
+    ngx_str_t                  path;
+    ngx_err_t                  err;
+    ngx_log_t                 *log;
+    ngx_buf_t                 *b;
+    ngx_chain_t                out;
+    ngx_file_info_t            fi;
+    ngx_pool_cleanup_file_t   *cln;
+    ngx_http_core_loc_conf_t  *clcf;
 
     if (r->uri.data[r->uri.len - 1] == '/') {
         return NGX_DECLINED;
@@ -106,99 +106,20 @@ ngx_http_static_handler(ngx_http_request
 
     log = r->connection->log;
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
     /*
-     * make a file name, reserve 2 bytes for a trailing '/'
-     * in a possible redirect and for the last '\0'
+     * ngx_http_map_uri_to_path() allocates memory for terminating '\0'
+     * so we do not need to reserve memory for '/' for possible redirect
      */
 
-    if (!clcf->alias) {
-        name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2);
-        if (name.data == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
-        last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
-
-        name.len = last - name.data;
-        location.len = last - location.data + 1;
-
-    } else {
-        name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2
-                                        - clcf->name.len);
-        if (name.data == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        last = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
-        last = ngx_cpystrn(last, r->uri.data + clcf->name.len,
-                           r->uri.len + 1 - clcf->name.len);
-
-        name.len = last - name.data;
-
-        location.data = ngx_palloc(r->pool, r->uri.len + 2);
-        if (location.data == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
-
-        location.len = last - location.data + 1;
+    last = ngx_http_map_uri_to_path(r, &path, 0);
+    if (last == NULL) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
-                   "http filename: \"%s\"", name.data);
-
-    /* open file */
-
-#if (NGX_WIN9X)
-
-    if (ngx_win32_version < NGX_WIN_NT) {
-
-        /*
-         * there is no way to open a file or a directory in Win9X with
-         * one syscall because Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag
-         * so we need to check its type before the opening
-         */
-
-        if (ngx_file_info(name.data, &fi) == NGX_FILE_ERROR) {
-            err = ngx_errno;
-            ngx_log_error(NGX_LOG_ERR, log, err,
-                          ngx_file_info_n " \"%s\" failed", name.data);
-
-            if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
-                return NGX_HTTP_NOT_FOUND;
-
-            } else if (err == NGX_EACCES) {
-                return NGX_HTTP_FORBIDDEN;
+                   "http filename: \"%s\"", path.data);
 
-            } else {
-                return NGX_HTTP_INTERNAL_SERVER_ERROR;
-            }
-        }
-
-        if (ngx_is_dir(&fi)) {
-            r->headers_out.location = ngx_http_add_header(&r->headers_out,
-                                                          ngx_http_headers_out);
-            if (r->headers_out.location == NULL) {
-                return NGX_HTTP_INTERNAL_SERVER_ERROR;
-            }
-
-            *last++ = '/';
-            *last = '\0';
-            r->headers_out.location->value.len = last - location;
-            r->headers_out.location->value.data = location;
-
-            return NGX_HTTP_MOVED_PERMANENTLY;
-        }
-    }
-
-#endif
-
-
-    fd = ngx_open_file(name.data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
+    fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
 
     if (fd == NGX_INVALID_FILE) {
         err = ngx_errno;
@@ -219,9 +140,11 @@ ngx_http_static_handler(ngx_http_request
             rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
         if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
             ngx_log_error(level, log, err,
-                          ngx_open_file_n " \"%s\" failed", name.data);
+                          ngx_open_file_n " \"%s\" failed", path.data);
         }
 
         return rc;
@@ -231,11 +154,11 @@ ngx_http_static_handler(ngx_http_request
 
     if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
         ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
-                      ngx_fd_info_n " \"%s\" failed", name.data);
+                      ngx_fd_info_n " \"%s\" failed", path.data);
 
         if (ngx_close_file(fd) == NGX_FILE_ERROR) {
             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                          ngx_close_file_n " \"%s\" failed", name.data);
+                          ngx_close_file_n " \"%s\" failed", path.data);
         }
 
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -247,23 +170,37 @@ ngx_http_static_handler(ngx_http_request
 
         if (ngx_close_file(fd) == NGX_FILE_ERROR) {
             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                          ngx_close_file_n " \"%s\" failed", name.data);
+                          ngx_close_file_n " \"%s\" failed", path.data);
         }
 
-        *last++ = '/';
-        *last = '\0';
-
         r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
         if (r->headers_out.location == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+        if (!clcf->alias) {
+            location = path.data + clcf->root.len;
+
+        } else {
+            location = ngx_palloc(r->pool, r->uri.len + 1);
+            if (location == NULL) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            last = ngx_cpymem(location, r->uri.data, r->uri.len);
+        }
+
+        *last = '/';
+
         /*
          * we do not need to set the r->headers_out.location->hash and
          * r->headers_out.location->key fields
          */
 
-        r->headers_out.location->value = location;
+        r->headers_out.location->value.len = r->uri.len + 1;
+        r->headers_out.location->value.data = location;
 
         return NGX_HTTP_MOVED_PERMANENTLY;
     }
@@ -272,11 +209,11 @@ ngx_http_static_handler(ngx_http_request
 
     if (!ngx_is_file(&fi)) {
         ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
-                      "\"%s\" is not a regular file", name.data);
+                      "\"%s\" is not a regular file", path.data);
 
         if (ngx_close_file(fd) == NGX_FILE_ERROR) {
             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                          ngx_close_file_n " \"%s\" failed", name.data);
+                          ngx_close_file_n " \"%s\" failed", path.data);
         }
 
         return NGX_HTTP_NOT_FOUND;
@@ -292,7 +229,7 @@ ngx_http_static_handler(ngx_http_request
     }
 
     cln->fd = fd;
-    cln->name = name.data;
+    cln->name = path.data;
     cln->log = r->pool->log;
 
     if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) {
@@ -349,7 +286,7 @@ ngx_http_static_handler(ngx_http_request
     b->file_last = ngx_file_size(&fi);
 
     b->file->fd = fd;
-    b->file->name = name;
+    b->file->name = path;
     b->file->log = log;
 
     out.buf = b;
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -911,37 +911,6 @@ ngx_http_set_content_type(ngx_http_reque
 
 
 ngx_int_t
-ngx_http_send_header(ngx_http_request_t *r)
-{
-    if (r->err_status) {
-        r->headers_out.status = r->err_status;
-        r->headers_out.status_line.len = 0;
-    }
-
-    return ngx_http_top_header_filter(r);
-}
-
-
-ngx_int_t
-ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
-    ngx_int_t  rc;
-
-    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http output filter \"%V\"", &r->uri);
-
-    rc = ngx_http_top_body_filter(r, in);
-
-    if (rc == NGX_ERROR) {
-        /* NGX_ERROR may be returned by any filter */
-        r->connection->closed = 1;
-    }
-
-    return rc;
-}
-
-
-ngx_int_t
 ngx_http_set_exten(ngx_http_request_t *r)
 {
     ngx_int_t  i;
@@ -977,6 +946,63 @@ ngx_http_set_exten(ngx_http_request_t *r
 
 
 ngx_int_t
+ngx_http_send_header(ngx_http_request_t *r)
+{
+    if (r->err_status) {
+        r->headers_out.status = r->err_status;
+        r->headers_out.status_line.len = 0;
+    }
+
+    return ngx_http_top_header_filter(r);
+}
+
+
+ngx_int_t
+ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
+{
+    ngx_int_t  rc;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http output filter \"%V\"", &r->uri);
+
+    rc = ngx_http_top_body_filter(r, in);
+
+    if (rc == NGX_ERROR) {
+        /* NGX_ERROR may be returned by any filter */
+        r->connection->closed = 1;
+    }
+
+    return rc;
+}
+
+
+u_char *
+ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
+    size_t reserved)
+{
+    u_char                    *last;
+    size_t                     alias;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    alias = clcf->alias ? clcf->name.len : 0;
+
+    path->len = clcf->root.len + r->uri.len - alias + 1 + reserved;
+
+    path->data = ngx_palloc(r->pool, path->len);
+    if (path->data == NULL) {
+        return NULL;
+    }
+
+    last = ngx_cpymem(path->data, clcf->root.data, clcf->root.len);
+    last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
+
+    return last;
+}
+
+
+ngx_int_t
 ngx_http_auth_basic_user(ngx_http_request_t *r)
 {
     ngx_str_t   auth, encoded;
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -253,6 +253,8 @@ ngx_int_t ngx_http_find_location_config(
 
 ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
 ngx_int_t ngx_http_set_exten(ngx_http_request_t *r);
+u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
+    size_t reserved);
 ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r);
 
 ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2234,7 +2234,7 @@ ngx_http_set_lingering_close(ngx_http_re
     rev = c->read;
     rev->handler = ngx_http_lingering_close_handler;
 
-    r->lingering_time = ngx_time() + clcf->lingering_time / 1000;
+    r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
     ngx_add_timer(rev, clcf->lingering_timeout);
 
     if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -619,8 +619,6 @@ ngx_http_variable_document_root(ngx_http
 static ngx_http_variable_value_t *
 ngx_http_variable_request_filename(ngx_http_request_t *r, uintptr_t data)
 {
-    u_char                     *p;
-    ngx_http_core_loc_conf_t   *clcf;
     ngx_http_variable_value_t  *vv;
 
     vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
@@ -630,29 +628,13 @@ ngx_http_variable_request_filename(ngx_h
 
     vv->value = 0;
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
-    if (!clcf->alias) {
-        vv->text.len = clcf->root.len + r->uri.len;
-        vv->text.data = ngx_palloc(r->pool, vv->text.len);
-        if (vv->text.data == NULL) {
-            return NULL;
-        }
-
-        p = ngx_cpymem(vv->text.data, clcf->root.data, clcf->root.len);
-        ngx_memcpy(p, r->uri.data, r->uri.len + 1);
+    if (ngx_http_map_uri_to_path(r, &vv->text, 0) == NULL) {
+        return NULL;
+    }
 
-    } else {
-        vv->text.len = clcf->root.len + r->uri.len + 2 - clcf->name.len;
-        vv->text.data = ngx_palloc(r->pool, vv->text.len);
-        if (vv->text.data == NULL) {
-            return NULL;
-        }
+    /* ngx_http_map_uri_to_path() allocates memory for terminating '\0' */
 
-        p = ngx_cpymem(vv->text.data, clcf->root.data, clcf->root.len);
-        ngx_memcpy(p, r->uri.data + clcf->name.len,
-                   r->uri.len + 1 - clcf->name.len);
-    }
+    vv->text.len--;
 
     return vv;
 }
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -67,6 +67,10 @@ ngx_os_status(ngx_log_t *log)
 {
     ngx_log_error(NGX_LOG_NOTICE, log, 0, NGINX_VER);
 
+#ifdef NGX_COMPILER
+    ngx_log_error(NGX_LOG_NOTICE, log, 0, "built by " NGX_COMPILER);
+#endif
+
 #if (NGX_HAVE_OS_SPECIFIC_INIT)
     ngx_os_specific_status(log);
 #endif
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -354,11 +354,6 @@ ngx_signal_handler(int signo)
             break;
 
         case SIGALRM:
-            if (!ngx_terminate) {
-                ngx_timer = 1;
-                action = ", shutting down old worker processes";
-            }
-
             break;
 
         case SIGIO:
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -33,7 +33,6 @@ ngx_pid_t     ngx_pid;
 ngx_uint_t    ngx_threaded;
 
 sig_atomic_t  ngx_reap;
-sig_atomic_t  ngx_timer;
 sig_atomic_t  ngx_sigio;
 sig_atomic_t  ngx_terminate;
 sig_atomic_t  ngx_quit;
@@ -194,19 +193,6 @@ ngx_master_process_cycle(ngx_cycle_t *cy
             continue;
         }
 
-        if (ngx_timer) {
-            ngx_timer = 0;
-
-            if (!ngx_noaccepting) {
-                ngx_start_worker_processes(cycle, ccf->worker_processes,
-                                           NGX_PROCESS_JUST_RESPAWN);
-                ngx_start_garbage_collector(cycle, NGX_PROCESS_JUST_RESPAWN);
-                live = 1;
-                ngx_signal_worker_processes(cycle,
-                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
-            }
-        }
-
         if (ngx_reconfigure) {
             ngx_reconfigure = 0;
 
@@ -320,9 +306,8 @@ ngx_single_process_cycle(ngx_cycle_t *cy
 static void
 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
 {
-    ngx_int_t         i;
-    ngx_channel_t     ch;
-    struct itimerval  itv;
+    ngx_int_t      i;
+    ngx_channel_t  ch;
 
     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
 
@@ -357,22 +342,6 @@ ngx_start_worker_processes(ngx_cycle_t *
                               &ch, sizeof(ngx_channel_t), cycle->log);
         }
     }
-
-    /*
-     * we have to limit the maximum life time of the worker processes
-     * by 10 days because our millisecond event timer is limited
-     * by 24 days on 32-bit platforms
-     */
-
-    itv.it_interval.tv_sec = 0;
-    itv.it_interval.tv_usec = 0;
-    itv.it_value.tv_sec = 10 * 24 * 60 * 60;
-    itv.it_value.tv_usec = 0;
-
-    if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                      "setitimer() failed");
-    }
 }
 
 
@@ -811,17 +780,9 @@ ngx_worker_process_init(ngx_cycle_t *cyc
     ngx_int_t          n;
     ngx_uint_t         i;
     struct rlimit      rlmt;
-    struct timeval     tv;
     ngx_core_conf_t   *ccf;
     ngx_listening_t   *ls;
 
-    ngx_gettimeofday(&tv);
-
-    ngx_start_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
-    ngx_old_elapsed_msec = 0;
-    ngx_elapsed_msec = 0;
-
-
     ngx_process = NGX_PROCESS_WORKER;
 
     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
--- a/src/os/unix/ngx_process_cycle.h
+++ b/src/os/unix/ngx_process_cycle.h
@@ -37,7 +37,6 @@ extern ngx_uint_t      ngx_threaded;
 extern ngx_uint_t      ngx_exiting;
 
 extern sig_atomic_t    ngx_reap;
-extern sig_atomic_t    ngx_timer;
 extern sig_atomic_t    ngx_sigio;
 extern sig_atomic_t    ngx_quit;
 extern sig_atomic_t    ngx_debug_quit;
--- a/src/os/unix/ngx_time.h
+++ b/src/os/unix/ngx_time.h
@@ -12,33 +12,31 @@
 #include <ngx_core.h>
 
 
-typedef uint64_t       ngx_epoch_msec_t;
+typedef ngx_rbtree_key_t  ngx_msec_t;
 
-typedef ngx_int_t      ngx_msec_t;
-
-typedef struct tm      ngx_tm_t;
+typedef struct tm         ngx_tm_t;
 
-#define ngx_tm_sec     tm_sec
-#define ngx_tm_min     tm_min
-#define ngx_tm_hour    tm_hour
-#define ngx_tm_mday    tm_mday
-#define ngx_tm_mon     tm_mon
-#define ngx_tm_year    tm_year
-#define ngx_tm_wday    tm_wday
-#define ngx_tm_isdst   tm_isdst
+#define ngx_tm_sec        tm_sec
+#define ngx_tm_min        tm_min
+#define ngx_tm_hour       tm_hour
+#define ngx_tm_mday       tm_mday
+#define ngx_tm_mon        tm_mon
+#define ngx_tm_year       tm_year
+#define ngx_tm_wday       tm_wday
+#define ngx_tm_isdst      tm_isdst
 
-#define ngx_tm_sec_t   int
-#define ngx_tm_min_t   int
-#define ngx_tm_hour_t  int
-#define ngx_tm_mday_t  int
-#define ngx_tm_mon_t   int
-#define ngx_tm_year_t  int
-#define ngx_tm_wday_t  int
+#define ngx_tm_sec_t      int
+#define ngx_tm_min_t      int
+#define ngx_tm_hour_t     int
+#define ngx_tm_mday_t     int
+#define ngx_tm_mon_t      int
+#define ngx_tm_year_t     int
+#define ngx_tm_wday_t     int
 
 
 #if (NGX_HAVE_GMTOFF)
-#define ngx_tm_gmtoff  tm_gmtoff
-#define ngx_tm_zone    tm_zone
+#define ngx_tm_gmtoff     tm_gmtoff
+#define ngx_tm_zone       tm_zone
 #endif