nginx-0.1.21-RELEASE import

    *) Bugfix: the ngx_http_stub_status_module showed incorrect statistics
       if "rtsig" method was used or if several worker process ran on SMP.

    *) Bugfix: nginx could not be built by the icc compiler on Linux or if
       the zlib-1.2.x library was building from sources.

    *) Bugfix: nginx could not be built on NetBSD 2.0.
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 0e75083..5c41207 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.1.20"
+#define NGINX_VER          "nginx/0.1.21"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_NEWPID_EXT     ".newbin"
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index 5479faa..4d5d0c8 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -114,7 +114,7 @@
 
     ngx_buf_t          *buffer;
 
-    ngx_uint_t          number;
+    ngx_atomic_int_t    number;
 
     unsigned            log_error:2;     /* ngx_connection_log_error_e */
 
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index cc03d79..e06b8ca 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -8,11 +8,12 @@
 #include <ngx_core.h>
 
 
-static ngx_uint_t ngx_temp_number;
-static ngx_uint_t ngx_random;
+static ngx_atomic_int_t  ngx_temp_number;
+static ngx_atomic_int_t  ngx_random;
 
 
-ssize_t ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain)
+ssize_t
+ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain)
 {
     ngx_int_t  rc;
 
@@ -33,13 +34,14 @@
 }
 
 
-ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
-                               ngx_pool_t *pool, int persistent)
+ngx_int_t
+ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
+    int persistent)
 {
-    ngx_err_t   err;
-    uint32_t    num;
+    ngx_err_t          err;
+    ngx_atomic_int_t   n;
 
-    file->name.len = path->name.len + 1 + path->len + 10;
+    file->name.len = path->name.len + 1 + path->len + NGX_ATOMIC_T_LEN;
 
     if (!(file->name.data = ngx_palloc(pool, file->name.len + 1))) {
         return NGX_ERROR;
@@ -53,11 +55,11 @@
 
     ngx_memcpy(file->name.data, path->name.data, path->name.len);
 
-    num = (uint32_t) ngx_next_temp_number(0);
+    n = ngx_next_temp_number(0);
 
     for ( ;; ) {
         ngx_sprintf(file->name.data + path->name.len + 1 + path->len,
-                    "%010ui%Z", num);
+                    "%0muA%Z", n);
 
         ngx_create_hashed_filename(file, path);
 
@@ -77,7 +79,7 @@
         err = ngx_errno;
 
         if (err == NGX_EEXIST) {
-            num = ngx_next_temp_number(1);
+            n = ngx_next_temp_number(1);
             continue;
         }
 
@@ -101,7 +103,8 @@
 }
 
 
-void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path)
+void
+ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path)
 {
     ngx_uint_t  i, name, pos, level;
 
@@ -128,7 +131,8 @@
 }
 
 
-ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path)
+ngx_int_t
+ngx_create_path(ngx_file_t *file, ngx_path_t *path)
 {
     int        i, pos;
     ngx_err_t  err;
@@ -164,19 +168,16 @@
 }
 
 
-void ngx_init_temp_number()
+void
+ngx_init_temp_number()
 {
-    ngx_random = 0;
-
-    ngx_temp_number = ngx_random;
-
-    while (ngx_random < 10000) {
-        ngx_random = 123456;
-    }
+    ngx_temp_number = 0;
+    ngx_random = 123456;
 }
 
 
-ngx_uint_t ngx_next_temp_number(ngx_uint_t collision)
+ngx_atomic_int_t
+ngx_next_temp_number(ngx_uint_t collision)
 {
     if (collision) {
         ngx_temp_number += ngx_random;
@@ -186,7 +187,8 @@
 }
 
 
-char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+char *
+ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     char  *p = conf;
 
@@ -237,7 +239,8 @@
 }
 
 
-ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
+ngx_int_t
+ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
 {
     ngx_uint_t   i, n;
     ngx_path_t  *path, **p;
@@ -299,7 +302,8 @@
 }
 
 
-ngx_int_t ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user)
+ngx_int_t
+ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user)
 {
     ngx_err_t         err;
     ngx_uint_t        i;
diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h
index bc64ed8..a76a648 100644
--- a/src/core/ngx_file.h
+++ b/src/core/ngx_file.h
@@ -55,14 +55,14 @@
 
 ssize_t ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain);
 ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
-                               ngx_pool_t *pool, int persistent);
+    ngx_pool_t *pool, int persistent);
 void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path);
 ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path);
 ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot);
 ngx_int_t ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user);
 
 void ngx_init_temp_number();
-ngx_uint_t ngx_next_temp_number(ngx_uint_t collision);
+ngx_atomic_int_t ngx_next_temp_number(ngx_uint_t collision);
 
 char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 
diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c
index d9c5c59..58894e9 100644
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -87,15 +87,9 @@
     p = ngx_sprintf(p, "%P#" NGX_TID_T_FMT ": ", ngx_log_pid, ngx_log_tid);
 
     if (log->connection) {
-        p = ngx_sprintf(p, "*%ui ", log->connection);
+        p = ngx_sprintf(p, "*%uA ", log->connection);
     }
 
-#if 0
-    if (log->data && *(int *) log->data != -1) {
-        p = ngx_sprintf(p, "*%ud ", *(u_int *) log->data);
-    }
-#endif
-
 #if (NGX_HAVE_VARIADIC_MACROS)
 
     va_start(args, fmt);
diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h
index 588837f..95dfe41 100644
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -47,7 +47,7 @@
     ngx_uint_t           log_level;
     ngx_open_file_t     *file;
 
-    ngx_uint_t           connection;
+    ngx_atomic_int_t     connection;
 
     ngx_log_handler_pt   handler;
     void                *data;
diff --git a/src/core/ngx_radix_tree.c b/src/core/ngx_radix_tree.c
index fa056af..2024219 100644
--- a/src/core/ngx_radix_tree.c
+++ b/src/core/ngx_radix_tree.c
@@ -40,8 +40,8 @@
     }
 
     /*
-     * We preallocate the first nodes: 0, 1, 00, 01, 10, 11, 000, 001, etc.,
-     * to increase the TLB hits even if for the first lookup iterations.
+     * The preallocation the first nodes: 0, 1, 00, 01, 10, 11, 000, 001, etc.
+     * increases the TLB hits even if for the first lookup iterations.
      * On the 32-bit platforms the 7 preallocated bits takes continuous 4K,
      * 8 - 8K, 9 - 16K, etc.  On the 64-bit platforms the 6 preallocated bits
      * takes continuous 4K, 7 - 8K, 8 - 16K, etc.  There is no sense to
diff --git a/src/core/ngx_rbtree.c b/src/core/ngx_rbtree.c
index ef57289..d3bb3a5 100644
--- a/src/core/ngx_rbtree.c
+++ b/src/core/ngx_rbtree.c
@@ -21,15 +21,14 @@
 
 
 static ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_t **root,
-                                              ngx_rbtree_t *sentinel,
-                                              ngx_rbtree_t *node);
+    ngx_rbtree_t *sentinel, ngx_rbtree_t *node);
 static ngx_inline void ngx_rbtree_right_rotate(ngx_rbtree_t **root,
-                                               ngx_rbtree_t *sentinel,
-                                               ngx_rbtree_t *node);
+    ngx_rbtree_t *sentinel, ngx_rbtree_t *node);
 
 
-void ngx_rbtree_insert(ngx_rbtree_t **root, ngx_rbtree_t *sentinel,
-                       ngx_rbtree_t *node)
+void
+ngx_rbtree_insert(ngx_rbtree_t **root, ngx_rbtree_t *sentinel,
+    ngx_rbtree_t *node)
 {
     ngx_rbtree_t  *temp;
 
@@ -125,8 +124,9 @@
 }
 
 
-void ngx_rbtree_delete(ngx_rbtree_t **root, ngx_rbtree_t *sentinel,
-                       ngx_rbtree_t *node)
+void
+ngx_rbtree_delete(ngx_rbtree_t **root, ngx_rbtree_t *sentinel,
+    ngx_rbtree_t *node)
 {
     ngx_int_t      is_red;
     ngx_rbtree_t  *subst, *temp, *w;
@@ -289,9 +289,9 @@
 }
 
 
-static ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_t **root,
-                                              ngx_rbtree_t *sentinel,
-                                              ngx_rbtree_t *node)
+static ngx_inline void
+ngx_rbtree_left_rotate(ngx_rbtree_t **root, ngx_rbtree_t *sentinel,
+    ngx_rbtree_t *node)
 {
     ngx_rbtree_t  *temp;
 
@@ -319,9 +319,9 @@
 }
 
 
-static ngx_inline void ngx_rbtree_right_rotate(ngx_rbtree_t **root,
-                                               ngx_rbtree_t *sentinel,
-                                               ngx_rbtree_t *node)
+static ngx_inline void
+ngx_rbtree_right_rotate(ngx_rbtree_t **root, ngx_rbtree_t *sentinel,
+    ngx_rbtree_t *node)
 {
     ngx_rbtree_t  *temp;
 
diff --git a/src/core/ngx_rbtree.h b/src/core/ngx_rbtree.h
index d876ec0..c8b7092 100644
--- a/src/core/ngx_rbtree.h
+++ b/src/core/ngx_rbtree.h
@@ -24,13 +24,13 @@
 
 
 void ngx_rbtree_insert(ngx_rbtree_t **root, ngx_rbtree_t *sentinel,
-                       ngx_rbtree_t *node);
+    ngx_rbtree_t *node);
 void ngx_rbtree_delete(ngx_rbtree_t **root, ngx_rbtree_t *sentinel,
-                       ngx_rbtree_t *node);
+    ngx_rbtree_t *node);
 
 
-static ngx_inline ngx_rbtree_t *ngx_rbtree_min(ngx_rbtree_t *node,
-                                               ngx_rbtree_t *sentinel)
+static ngx_inline ngx_rbtree_t *
+ngx_rbtree_min(ngx_rbtree_t *node, ngx_rbtree_t *sentinel)
 {
    while (node->left != sentinel) {
        node = node->left;
diff --git a/src/core/ngx_spinlock.c b/src/core/ngx_spinlock.c
index dfa7da4..00e7fca 100644
--- a/src/core/ngx_spinlock.c
+++ b/src/core/ngx_spinlock.c
@@ -8,6 +8,10 @@
 #include <ngx_core.h>
 
 
+/*
+ * TODO: the P4 optimized assembler version with the "pause" operation
+ */
+
 void ngx_spinlock(ngx_atomic_t *lock, ngx_uint_t spin)
 {
 
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index d63a238..ca9d669 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -8,7 +8,8 @@
 #include <ngx_core.h>
 
 
-u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n)
+u_char *
+ngx_cpystrn(u_char *dst, u_char *src, size_t n)
 {
     if (n == 0) {
         return dst;
@@ -28,7 +29,8 @@
 }
 
 
-u_char *ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
+u_char *
+ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
 {
     u_char  *dst;
 
@@ -52,6 +54,7 @@
  *    %[0][width|m][u][x|X]i    ngx_int_t/ngx_uint_t
  *    %[0][width][u][x|X]D      int32_t/uint32_t
  *    %[0][width][u][x|X]L      int64_t/uint64_t
+ *    %[0][width|m][u][x|X]A    ngx_atomic_int_t
  *    %P                        ngx_pid_t
  *    %r                        rlim_t
  *    %p                        pointer
@@ -63,7 +66,6 @@
  *
  *  TODO:
  *    %M                        ngx_msec_t
- *    %A                        ngx_atomic_t
  *
  *  reserved:
  *    %t                        ptrdiff_t
@@ -72,7 +74,8 @@
  */
 
 
-u_char *ngx_sprintf(u_char *buf, const char *fmt, ...)
+u_char *
+ngx_sprintf(u_char *buf, const char *fmt, ...)
 {
     u_char   *p;
     va_list   args;
@@ -85,7 +88,8 @@
 }
 
 
-u_char *ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
+u_char *
+ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
 {
     u_char   *p;
     va_list   args;
@@ -98,12 +102,13 @@
 }
 
 
-u_char *ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
+u_char *
+ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
 {
     u_char         *p, zero, *last, temp[NGX_INT64_LEN + 1];
                                     /*
                                      * really we need temp[NGX_INT64_LEN] only,
-                                     * but icc shows the warning
+                                     * but icc issues the warning
                                      */
     int             d;
     size_t          len;
@@ -111,7 +116,7 @@
     int64_t         i64;
     uint64_t        ui64;
     ngx_str_t      *s;
-    ngx_uint_t      width, sign, hexadecimal;
+    ngx_uint_t      width, sign, hexadecimal, max_width;
     static u_char   hex[] = "0123456789abcdef";
     static u_char   HEX[] = "0123456789ABCDEF";
 
@@ -137,6 +142,7 @@
             width = 0;
             sign = 1;
             hexadecimal = 0;
+            max_width = 0;
 
             p = temp + NGX_INT64_LEN;
 
@@ -154,7 +160,7 @@
                     continue;
 
                 case 'm':
-                    width = NGX_INT_T_LEN;
+                    max_width = 1;
                     fmt++;
                     continue;
 
@@ -228,6 +234,11 @@
                 } else {
                     ui64 = (uint64_t) va_arg(args, ngx_uint_t);
                 }
+
+                if (max_width) {
+                    width = NGX_INT_T_LEN;
+                }
+
                 break;
 
             case 'd':
@@ -262,6 +273,19 @@
                 }
                 break;
 
+            case 'A':
+                if (sign) {
+                    i64 = (int64_t) va_arg(args, ngx_atomic_int_t);
+                } else {
+                    ui64 = (uint64_t) va_arg(args, ngx_atomic_int_t);
+                }
+
+                if (max_width) {
+                    width = NGX_ATOMIC_T_LEN;
+                }
+
+                break;
+
 #if !(NGX_WIN32)
             case 'r':
                 i64 = (int64_t) va_arg(args, rlim_t);
@@ -334,13 +358,15 @@
                  * To divide 64-bit number and to find the remainder
                  * on the x86 platform gcc and icc call the libc functions
                  * [u]divdi3() and [u]moddi3(), they call another function
-                 * in return.  On FreeBSD it is the qdivrem() function,
+                 * in its turn.  On FreeBSD it is the qdivrem() function,
                  * its source code is about 170 lines of the code.
                  * The glibc counterpart is about 150 lines of the code.
                  *
-                 * For 32-bit numbers gcc and icc use the inlined
-                 * multiplication and shifts.  For example, unsigned
-                 * "i32 / 10" is compiled to "(i32 * 0xCCCCCCCD) >> 35".
+                 * For 32-bit numbers and some divisors gcc and icc use
+                 * the inlined multiplication and shifts.  For example,
+                 * unsigned "i32 / 10" is compiled to
+                 *
+                 *     (i32 * 0xCCCCCCCD) >> 35
                  */
 
                 ui32 = (uint32_t) ui64;
@@ -379,7 +405,8 @@
 }
 
 
-ngx_int_t ngx_rstrncmp(u_char *s1, u_char *s2, size_t n)
+ngx_int_t
+ngx_rstrncmp(u_char *s1, u_char *s2, size_t n)
 {
     if (n == 0) {
         return 0;
@@ -401,7 +428,8 @@
 }
 
 
-ngx_int_t ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n)
+ngx_int_t
+ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n)
 {
     u_char  c1, c2;
 
@@ -435,7 +463,8 @@
 }
 
 
-ngx_int_t ngx_atoi(u_char *line, size_t n)
+ngx_int_t
+ngx_atoi(u_char *line, size_t n)
 {
     ngx_int_t  value;
 
@@ -460,7 +489,8 @@
 }
 
 
-ngx_int_t ngx_hextoi(u_char *line, size_t n)
+ngx_int_t
+ngx_hextoi(u_char *line, size_t n)
 {
     u_char     ch;
     ngx_int_t  value;
@@ -499,7 +529,8 @@
 }
 
 
-void ngx_md5_text(u_char *text, u_char *md5)
+void
+ngx_md5_text(u_char *text, u_char *md5)
 {
     int            i;
     static u_char  hex[] = "0123456789abcdef";
@@ -513,7 +544,8 @@
 }
 
 
-void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)
+void
+ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)
 {
     u_char         *d, *s;
     size_t          len;
@@ -553,7 +585,8 @@
 }
 
 
-ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
+ngx_int_t
+ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
 {
     size_t          len;
     u_char         *d, *s;
@@ -616,19 +649,20 @@
 }
 
 
-uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
+uintptr_t
+ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
 {
     ngx_uint_t        i, n;
     uint32_t         *escape;
     static u_char     hex[] = "0123456789abcdef";
 
-                      /* " ", "%", "?", %00-%1F, %7F-%FF */
+                      /* " ", "#", "%", "?", %00-%1F, %7F-%FF */
 
     static uint32_t   uri[] =
         { 0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
                       /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
-          0x80000021, /* 1000 0000 0000 0000  0000 0000 0010 0001 */
+          0x80000029, /* 1000 0000 0000 0000  0000 0000 0010 1001 */
 
                       /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
           0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
@@ -641,13 +675,13 @@
           0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
           0xffffffff  /* 1111 1111 1111 1111  1111 1111 1111 1111 */ };
 
-                      /* " ", "%", "+", "?", %00-%1F, %7F-%FF */
+                      /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
 
     static uint32_t   args[] =
         { 0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
                       /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
-          0x80000821, /* 1000 0000 0000 0000  0000 1000 0010 0001 */
+          0x80000829, /* 1000 0000 0000 0000  0000 1000 0010 1001 */
 
                       /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
           0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
@@ -666,7 +700,7 @@
         { 0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
                       /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
-          0x80000021, /* 0000 0000 0000 0000  0000 0000 1010 0101 */
+          0x800000ad, /* 0000 0000 0000 0000  0000 0000 1010 1101 */
 
                       /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
           0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index 7668807..52bac6a 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -98,7 +98,7 @@
 #define NGX_ESCAPE_HTML  2
 
 uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size,
-                         ngx_uint_t type);
+    ngx_uint_t type);
 
 
 #define  ngx_qsort                qsort