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
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index d017f05..f1df549 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -701,18 +701,18 @@
name[0] = CTL_KERN;
name[1] = KERN_RTSIGMAX;
len = sizeof(rtsig_max);
- if (sysctl(name, sizeof(name), &rtsig_max, &len, NULL, 0) == -1)
- {
+
+ if (sysctl(name, 2, &rtsig_max, &len, NULL, 0) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
"sysctl(KERN_RTSIGMAX) failed");
return NGX_ERROR;
}
- name[0] = CTL_KERN;
+ /* name[0] = CTL_KERN; */
name[1] = KERN_RTSIGNR;
len = sizeof(rtsig_nr);
- if (sysctl(name, sizeof(name), &rtsig_nr, &len, NULL, 0) == -1)
- {
+
+ if (sysctl(name, 2, &rtsig_nr, &len, NULL, 0) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
"sysctl(KERN_RTSIGNR) failed");
return NGX_ERROR;
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index d79e5ff..780dbeb 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -34,21 +34,21 @@
static char *ngx_accept_mutex_check(ngx_conf_t *cf, void *post, void *data);
-static ngx_uint_t ngx_event_max_module;
+static ngx_uint_t ngx_event_max_module;
-ngx_uint_t ngx_event_flags;
-ngx_event_actions_t ngx_event_actions;
+ngx_uint_t ngx_event_flags;
+ngx_event_actions_t ngx_event_actions;
-ngx_atomic_t connection_counter;
-ngx_atomic_t *ngx_connection_counter = &connection_counter;
+ngx_atomic_t connection_counter;
+ngx_atomic_t *ngx_connection_counter = &connection_counter;
-ngx_atomic_t *ngx_accept_mutex_ptr;
-ngx_atomic_t *ngx_accept_mutex;
-ngx_uint_t ngx_accept_mutex_held;
-ngx_msec_t ngx_accept_mutex_delay;
-ngx_int_t ngx_accept_disabled;
+ngx_atomic_t *ngx_accept_mutex_ptr;
+ngx_atomic_t *ngx_accept_mutex;
+ngx_uint_t ngx_accept_mutex_held;
+ngx_msec_t ngx_accept_mutex_delay;
+ngx_int_t ngx_accept_disabled;
#if (NGX_STAT_STUB)
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index c7f7595..fb2d984 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -7,14 +7,14 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
-#include <nginx.h>
static void ngx_close_accepted_socket(ngx_socket_t s, ngx_log_t *log);
static u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
-void ngx_event_accept(ngx_event_t *ev)
+void
+ngx_event_accept(ngx_event_t *ev)
{
ngx_uint_t instance, accepted;
socklen_t len;
@@ -53,7 +53,7 @@
/*
* Create the pool before accept() to avoid the copying of
* the sockaddr. Although accept() can fail it is uncommon
- * case and besides the pool can be got from the free pool list
+ * case and besides the pool can be got from the free pool list.
*/
if (!(pool = ngx_create_pool(ls->listening->pool_size, ev->log))) {
@@ -117,7 +117,7 @@
}
#if (NGX_STAT_STUB)
- (*ngx_stat_accepted)++;
+ ngx_atomic_inc(ngx_stat_accepted);
#endif
ngx_accept_disabled = (ngx_uint_t) s + NGX_ACCEPT_THRESHOLD
@@ -139,7 +139,7 @@
}
#if (NGX_STAT_STUB)
- (*ngx_stat_active)++;
+ ngx_atomic_inc(ngx_stat_active);
#endif
/* set a blocking mode for aio and non-blocking mode for others */
@@ -234,7 +234,7 @@
wev->ready = 1;
if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT)) {
- /* epoll, rtsig, aio, iocp */
+ /* rtsig, aio, iocp */
rev->ready = 1;
}
@@ -336,7 +336,8 @@
}
-ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
+ngx_int_t
+ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
{
if (*ngx_accept_mutex == 0
&& ngx_atomic_cmp_set(ngx_accept_mutex, 0, ngx_pid))
@@ -368,7 +369,8 @@
}
-ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle)
+ngx_int_t
+ngx_enable_accept_events(ngx_cycle_t *cycle)
{
ngx_uint_t i;
ngx_listening_t *s;
@@ -400,7 +402,8 @@
}
-ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle)
+ngx_int_t
+ngx_disable_accept_events(ngx_cycle_t *cycle)
{
ngx_uint_t i;
ngx_listening_t *s;
@@ -442,7 +445,8 @@
}
-static void ngx_close_accepted_socket(ngx_socket_t s, ngx_log_t *log)
+static void
+ngx_close_accepted_socket(ngx_socket_t s, ngx_log_t *log)
{
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
@@ -451,7 +455,8 @@
}
-static u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len)
+static u_char *
+ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len)
{
return ngx_snprintf(buf, len, " while accept() on %V", log->data);
}
diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c
index c1ca124..4b98656 100644
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -18,7 +18,8 @@
ngx_rbtree_t ngx_event_timer_sentinel;
-ngx_int_t ngx_event_timer_init(ngx_log_t *log)
+ngx_int_t
+ngx_event_timer_init(ngx_log_t *log)
{
if (ngx_event_timer_rbtree) {
#if (NGX_THREADS)
@@ -39,7 +40,8 @@
}
-ngx_msec_t ngx_event_find_timer(void)
+ngx_msec_t
+ngx_event_find_timer(void)
{
ngx_msec_t timer;
ngx_rbtree_t *node;
@@ -68,7 +70,8 @@
}
-void ngx_event_expire_timers(ngx_msec_t timer)
+void
+ngx_event_expire_timers(ngx_msec_t timer)
{
ngx_event_t *ev;
ngx_rbtree_t *node;
diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h
index 090d404..edbfcf6 100644
--- a/src/event/ngx_event_timer.h
+++ b/src/event/ngx_event_timer.h
@@ -16,8 +16,9 @@
#define NGX_TIMER_INFINITE -1
#define NGX_TIMER_ERROR -2
+
/*
- * 32 bit timer key value resolution
+ * the 32-bit timer key value resolution
*
* 1 msec - 24 days
* 10 msec - 8 months
@@ -27,6 +28,8 @@
#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);
@@ -42,7 +45,8 @@
extern ngx_rbtree_t ngx_event_timer_sentinel;
-static ngx_inline void ngx_event_del_timer(ngx_event_t *ev)
+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",
@@ -68,7 +72,8 @@
}
-static ngx_inline void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
+static ngx_inline void
+ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
{
ngx_int_t key;
@@ -83,11 +88,13 @@
/*
* Use the previous timer value if a difference between them is less
- * then 100 milliseconds. It allows to minimize the rbtree operations
- * for the fast connections.
+ * then NGX_TIMER_LAZY_DELAY milliseconds. It allows to minimize
+ * the rbtree operations for the fast connections.
*/
- if (abs(key - ev->rbtree_key) < 100 / NGX_TIMER_RESOLUTION) {
+ if (abs(key - ev->rbtree_key)
+ < NGX_TIMER_LAZY_DELAY / NGX_TIMER_RESOLUTION)
+ {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"event timer: %d, old: %i, new: %i",
ngx_event_ident(ev->data), ev->rbtree_key, key);
diff --git a/src/http/modules/ngx_http_range_filter.c b/src/http/modules/ngx_http_range_filter.c
index 8f98719..1eb4cc6 100644
--- a/src/http/modules/ngx_http_range_filter.c
+++ b/src/http/modules/ngx_http_range_filter.c
@@ -105,14 +105,15 @@
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r)
+static ngx_int_t
+ngx_http_range_header_filter(ngx_http_request_t *r)
{
u_char *p;
size_t len;
off_t start, end;
ngx_int_t rc;
- uint32_t boundary;
ngx_uint_t suffix, i;
+ ngx_atomic_int_t boundary;
ngx_table_elt_t *content_range;
ngx_http_range_t *range;
ngx_http_range_filter_ctx_t *ctx;
@@ -328,7 +329,8 @@
sizeof(ngx_http_range_filter_ctx_t), NGX_ERROR);
- len = sizeof(CRLF "--0123456789" CRLF "Content-Type: ") - 1
+ len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN
+ + sizeof(CRLF "Content-Type: ") - 1
+ r->headers_out.content_type->value.len
+ sizeof(CRLF "Content-Range: bytes ") - 1;
@@ -340,7 +342,7 @@
return NGX_ERROR;
}
- boundary = (uint32_t) ngx_next_temp_number(0);
+ boundary = ngx_next_temp_number(0);
/*
* The boundary header of the range:
@@ -352,7 +354,7 @@
if (r->headers_out.charset.len) {
ctx->boundary_header.len = ngx_sprintf(ctx->boundary_header.data,
- CRLF "--%010ud" CRLF
+ CRLF "--%0muA" CRLF
"Content-Type: %V; charset=%V" CRLF
"Content-Range: bytes ",
boundary,
@@ -364,7 +366,7 @@
} else {
ctx->boundary_header.len = ngx_sprintf(ctx->boundary_header.data,
- CRLF "--%010ud" CRLF
+ CRLF "--%0muA" CRLF
"Content-Type: %V" CRLF
"Content-Range: bytes ",
boundary,
@@ -373,8 +375,9 @@
}
r->headers_out.content_type->value.data =
- ngx_palloc(r->pool, sizeof("Content-Type: multipart/byteranges; "
- "boundary=0123456789") - 1);
+ ngx_palloc(r->pool,
+ sizeof("Content-Type: multipart/byteranges; boundary=") - 1
+ + NGX_ATOMIC_T_LEN);
if (r->headers_out.content_type->value.data == NULL) {
return NGX_ERROR;
@@ -384,12 +387,14 @@
r->headers_out.content_type->value.len =
ngx_sprintf(r->headers_out.content_type->value.data,
- "multipart/byteranges; boundary=%010ud",
+ "multipart/byteranges; boundary=%0muA",
boundary)
- r->headers_out.content_type->value.data;
+
/* the size of the last boundary CRLF "--0123456789--" CRLF */
- len = sizeof(CRLF "--0123456789--" CRLF) - 1;
+
+ len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN + sizeof("--" CRLF) - 1;
range = r->headers_out.ranges.elts;
for (i = 0; i < r->headers_out.ranges.nelts; i++) {
@@ -420,8 +425,8 @@
}
-static ngx_int_t ngx_http_range_body_filter(ngx_http_request_t *r,
- ngx_chain_t *in)
+static ngx_int_t
+ngx_http_range_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
ngx_uint_t i;
ngx_buf_t *b;
@@ -525,7 +530,8 @@
b->temporary = 1;
b->last_buf = 1;
- b->pos = ngx_palloc(r->pool, sizeof(CRLF "--0123456789--" CRLF) - 1);
+ b->pos = ngx_palloc(r->pool, sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN
+ + sizeof("--" CRLF) - 1);
if (b->pos == NULL) {
return NGX_ERROR;
}
@@ -552,7 +558,8 @@
}
-static ngx_int_t ngx_http_range_header_filter_init(ngx_cycle_t *cycle)
+static ngx_int_t
+ngx_http_range_header_filter_init(ngx_cycle_t *cycle)
{
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_range_header_filter;
@@ -561,7 +568,8 @@
}
-static ngx_int_t ngx_http_range_body_filter_init(ngx_cycle_t *cycle)
+static ngx_int_t
+ngx_http_range_body_filter_init(ngx_cycle_t *cycle)
{
ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_range_body_filter;
diff --git a/src/http/modules/ngx_http_stub_status_module.c b/src/http/modules/ngx_http_stub_status_module.c
index 3a35fe9..834beaa 100644
--- a/src/http/modules/ngx_http_stub_status_module.c
+++ b/src/http/modules/ngx_http_stub_status_module.c
@@ -102,15 +102,15 @@
rd = *ngx_stat_reading;
wr = *ngx_stat_writing;
- b->last = ngx_sprintf(b->last, "Active connections: %d \n", ac);
+ b->last = ngx_sprintf(b->last, "Active connections: %D \n", ac);
b->last = ngx_cpymem(b->last, "server accepts handled requests\n",
sizeof("server accepts handled requests\n") - 1);
- b->last = ngx_sprintf(b->last, " %d %d %d \n", ap, hn, rq);
+ b->last = ngx_sprintf(b->last, " %D %D %D \n", ap, hn, rq);
- b->last = ngx_sprintf(b->last, "Reading: %d Writing: %d Waiting: %d \n",
- rd, wr, ac - (rd + wr));
+ b->last = ngx_sprintf(b->last, "Reading: %D Writing: %D Waiting: %d \n",
+ rd, wr, ac - (rd + wr));
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = b->last - b->pos;
diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c
index 3610b1e..ea0907f 100644
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -117,7 +117,8 @@
};
-static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r)
+static ngx_int_t
+ngx_http_header_filter(ngx_http_request_t *r)
{
u_char *p;
size_t len;
@@ -146,8 +147,9 @@
}
}
- /* 2 is for trailing "\r\n" and 2 is for "\r\n" in the end of header */
- len = sizeof("HTTP/1.x ") - 1 + 2 + 2;
+ len = sizeof("HTTP/1.x ") - 1 + sizeof(CRLF) - 1
+ /* the end of the header */
+ + sizeof(CRLF) - 1;
/* status line */
@@ -279,8 +281,8 @@
continue;
}
- /* 2 is for ": " and 2 is for "\r\n" */
- len += header[i].key.len + 2 + header[i].value.len + 2;
+ len += header[i].key.len + sizeof(": ") - 1 + header[i].value.len
+ + sizeof(CRLF) - 1;
}
if (!(b = ngx_create_temp_buf(r->pool, len))) {
@@ -299,7 +301,7 @@
b->last = ngx_cpymem(b->last, http_codes[status].data,
http_codes[status].len);
}
- *(b->last++) = CR; *(b->last++) = LF;
+ *b->last++ = CR; *b->last++ = LF;
if (!(r->headers_out.server && r->headers_out.server->key.len)) {
b->last = ngx_cpymem(b->last, server_string, sizeof(server_string) - 1);
@@ -310,7 +312,7 @@
b->last = ngx_cpymem(b->last, ngx_cached_http_time.data,
ngx_cached_http_time.len);
- *(b->last++) = CR; *(b->last++) = LF;
+ *b->last++ = CR; *b->last++ = LF;
}
if (r->headers_out.content_length == NULL) {
@@ -337,7 +339,7 @@
r->headers_out.content_type->value.data = p;
}
- *(b->last++) = CR; *(b->last++) = LF;
+ *b->last++ = CR; *b->last++ = LF;
}
if (r->headers_out.location
@@ -360,7 +362,7 @@
r->headers_out.location->value.len = b->last - p;
r->headers_out.location->value.data = p;
- *(b->last++) = CR; *(b->last++) = LF;
+ *b->last++ = CR; *b->last++ = LF;
}
if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len)
@@ -370,7 +372,7 @@
sizeof("Last-Modified: ") - 1);
b->last = ngx_http_time(b->last, r->headers_out.last_modified_time);
- *(b->last++) = CR; *(b->last++) = LF;
+ *b->last++ = CR; *b->last++ = LF;
}
if (r->chunked) {
@@ -412,20 +414,20 @@
}
b->last = ngx_cpymem(b->last, header[i].key.data, header[i].key.len);
- *(b->last++) = ':' ; *(b->last++) = ' ' ;
+ *b->last++ = ':' ; *b->last++ = ' ' ;
b->last = ngx_cpymem(b->last, header[i].value.data,
header[i].value.len);
- *(b->last++) = CR; *(b->last++) = LF;
+ *b->last++ = CR; *b->last++ = LF;
}
#if (NGX_DEBUG)
- *(b->last) = '\0';
+ *b->last = '\0';
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "%s\n", b->pos);
#endif
/* the end of HTTP header */
- *(b->last++) = CR; *(b->last++) = LF;
+ *b->last++ = CR; *b->last++ = LF;
r->header_size = b->last - b->pos;
@@ -444,7 +446,8 @@
}
-static ngx_int_t ngx_http_header_filter_init(ngx_cycle_t *cycle)
+static ngx_int_t
+ngx_http_header_filter_init(ngx_cycle_t *cycle)
{
ngx_http_top_header_filter = ngx_http_header_filter;
diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c
index 0d031fe..148246f 100644
--- a/src/http/ngx_http_log_handler.c
+++ b/src/http/ngx_http_log_handler.c
@@ -135,7 +135,8 @@
ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = {
{ ngx_string("addr"), INET_ADDRSTRLEN - 1, NULL, NULL, ngx_http_log_addr },
- { ngx_string("conn"), NGX_INT32_LEN, NULL, NULL, ngx_http_log_connection },
+ { ngx_string("conn"), NGX_ATOMIC_T_LEN, NULL, NULL,
+ ngx_http_log_connection },
{ ngx_string("pipe"), 1, NULL, NULL, ngx_http_log_pipe },
{ ngx_string("time"), sizeof("28/Sep/1970:12:00:00 +0600") - 1,
NULL, NULL, ngx_http_log_time },
@@ -143,13 +144,13 @@
{ ngx_string("status"), 3, NULL, NULL, ngx_http_log_status },
{ ngx_string("length"), NGX_OFF_T_LEN, NULL, NULL, ngx_http_log_length },
{ ngx_string("apache_length"), NGX_OFF_T_LEN,
- NULL, NULL, ngx_http_log_apache_length },
+ NULL, NULL, ngx_http_log_apache_length },
{ ngx_string("request_length"), NGX_SIZE_T_LEN,
- NULL, NULL, ngx_http_log_request_length },
+ NULL, NULL, ngx_http_log_request_length },
{ ngx_string("request"), 0, NULL,
- ngx_http_log_request_getlen,
- ngx_http_log_request },
+ ngx_http_log_request_getlen,
+ ngx_http_log_request },
{ ngx_string("i"), 0, ngx_http_log_header_in_compile,
ngx_http_log_header_in_getlen,
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index a6046f1..f490847 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -138,6 +138,7 @@
if (ngx_accept_mutex) {
if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+
ngx_http_close_connection(c);
return;
}
@@ -145,11 +146,15 @@
ngx_post_event(rev);
ngx_mutex_unlock(ngx_posted_events_mutex);
+
+#if (NGX_STAT_STUB)
+ ngx_atomic_inc(ngx_stat_reading);
+#endif
return;
}
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)++;
+ ngx_atomic_inc(ngx_stat_reading);
#endif
ngx_http_init_request(rev);
@@ -176,7 +181,7 @@
#endif
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)++;
+ ngx_atomic_inc(ngx_stat_reading);
#endif
}
@@ -205,7 +210,7 @@
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)--;
+ ngx_atomic_dec(ngx_stat_reading);
#endif
ngx_http_close_connection(c);
@@ -217,14 +222,14 @@
if (hc) {
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)++;
+ ngx_atomic_inc(ngx_stat_reading);
#endif
} else {
if (!(hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)))) {
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)--;
+ ngx_atomic_dec(ngx_stat_reading);
#endif
ngx_http_close_connection(c);
@@ -247,7 +252,7 @@
if (!(r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)))) {
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)--;
+ ngx_atomic_dec(ngx_stat_reading);
#endif
ngx_http_close_connection(c);
@@ -258,7 +263,7 @@
}
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)--;
+ ngx_atomic_dec(ngx_stat_reading);
#endif
c->data = r;
@@ -427,9 +432,9 @@
r->http_state = NGX_HTTP_READING_REQUEST_STATE;
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)++;
+ ngx_atomic_inc(ngx_stat_reading);
r->stat_reading = 1;
- (*ngx_stat_requests)++;
+ ngx_atomic_inc(ngx_stat_requests);
#endif
rev->event_handler(rev);
@@ -829,9 +834,9 @@
}
#if (NGX_STAT_STUB)
- (*ngx_stat_reading)--;
+ ngx_atomic_dec(ngx_stat_reading);
r->stat_reading = 0;
- (*ngx_stat_writing)++;
+ ngx_atomic_inc(ngx_stat_writing);
r->stat_writing = 1;
#endif
@@ -2076,11 +2081,11 @@
#if (NGX_STAT_STUB)
if (r->stat_reading) {
- (*ngx_stat_reading)--;
+ ngx_atomic_dec(ngx_stat_reading);
}
if (r->stat_writing) {
- (*ngx_stat_writing)--;
+ ngx_atomic_dec(ngx_stat_writing);
}
#endif
@@ -2203,7 +2208,7 @@
#endif
#if (NGX_STAT_STUB)
- (*ngx_stat_active)--;
+ ngx_atomic_dec(ngx_stat_active);
#endif
pool = c->pool;
diff --git a/src/os/unix/ngx_atomic.h b/src/os/unix/ngx_atomic.h
index 2de61cf..c313964 100644
--- a/src/os/unix/ngx_atomic.h
+++ b/src/os/unix/ngx_atomic.h
@@ -12,11 +12,104 @@
#include <ngx_core.h>
-#if ( __i386__ || __amd64__ )
+#if ( __i386__ )
#define NGX_HAVE_ATOMIC_OPS 1
-typedef volatile uint32_t ngx_atomic_t;
+typedef uint32_t ngx_atomic_int_t;
+typedef volatile ngx_atomic_int_t ngx_atomic_t;
+#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+
+
+#if (NGX_SMP)
+#define NGX_SMP_LOCK "lock;"
+#else
+#define NGX_SMP_LOCK
+#endif
+
+/*
+ * the "=q" is any of the %eax, %ebx, %ecx, or %edx registers.
+ * the '"0" (1)' parameter preloads 1 into %0.
+ * the "cc" means that flags were changed.
+ */
+
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_inc(ngx_atomic_t *value)
+{
+ ngx_atomic_int_t old;
+
+ __asm__ volatile (
+
+ NGX_SMP_LOCK
+ " xaddl %0, %2; "
+ " incl %0; "
+
+ : "=q" (old) : "0" (1), "m" (*value) : "cc", "memory");
+
+ return old;
+}
+
+
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_dec(ngx_atomic_t *value)
+{
+ ngx_atomic_int_t old;
+
+ __asm__ volatile (
+
+ NGX_SMP_LOCK
+ " xaddl %0, %2; "
+ " decl %0; "
+
+ : "=q" (old) : "0" (-1), "m" (*value) : "cc", "memory");
+
+ return old;
+}
+
+
+/*
+ * the "q" is any of the %eax, %ebx, %ecx, or %edx registers.
+ * the "=a" and "a" are the %eax register. Although we can return result
+ * in any register, we use %eax because it is used in cmpxchg anyway.
+ *
+ * "cmpxchg r, [m]":
+ *
+ * if (eax == [m]) {
+ * zf = 1;
+ * [m] = r;
+ * } else {
+ * zf = 0;
+ * eax = [m];
+ * }
+ */
+
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old,
+ ngx_atomic_int_t set)
+{
+ ngx_atomic_int_t res;
+
+ __asm__ volatile (
+
+ NGX_SMP_LOCK
+ " cmpxchgl %3, %1; "
+ " setz %b0; "
+ " movzbl %b0, %0; "
+
+ : "=a" (res) : "m" (*lock), "a" (old), "q" (set) : "cc", "memory");
+
+ return res;
+}
+
+
+#elif ( __amd64__ )
+
+#define NGX_HAVE_ATOMIC_OPS 1
+
+typedef int64_t ngx_atomic_int_t;
+typedef volatile ngx_atomic_int_t ngx_atomic_t;
+#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
+
#if (NGX_SMP)
#define NGX_SMP_LOCK "lock;"
@@ -25,56 +118,58 @@
#endif
-static ngx_inline uint32_t ngx_atomic_inc(ngx_atomic_t *value)
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_inc(ngx_atomic_t *value)
{
- uint32_t old;
+ ngx_atomic_int_t old;
__asm__ volatile (
- NGX_SMP_LOCK
- " xaddl %0, %2; "
- " incl %0; "
+ NGX_SMP_LOCK
+ " xaddq %0, %2; "
+ " incq %0; "
- : "=q" (old) : "0" (1), "m" (*value));
+ : "=r" (old) : "0" (1), "m" (*value) : "cc", "memory");
return old;
}
-#if 0
+/* the '"0" (-1LL)' parameter preloads -1 into the 64-bit %0 register */
-static ngx_inline uint32_t ngx_atomic_dec(ngx_atomic_t *value)
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_dec(ngx_atomic_t *value)
{
- uint32_t old;
+ ngx_atomic_int_t old;
__asm__ volatile (
- NGX_SMP_LOCK
- " xaddl %0, %1; "
- " decl %0; "
+ NGX_SMP_LOCK
+ " xaddq %0, %2; "
+ " decq %0; "
- : "=q" (old) : "0" (-1), "m" (*value));
+ : "=r" (old) : "0" (-1LL), "m" (*value) : "cc", "memory");
return old;
}
-#endif
+/* the "=a" and "a" are the %rax register. */
-static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock,
- ngx_atomic_t old,
- ngx_atomic_t set)
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old,
+ ngx_atomic_int_t set)
{
- uint32_t res;
+ ngx_atomic_int_t res;
__asm__ volatile (
- NGX_SMP_LOCK
- " cmpxchgl %3, %1; "
- " setz %%al; "
- " movzbl %%al, %0; "
+ NGX_SMP_LOCK
+ " cmpxchgq %3, %1; "
+ " setz %b0; "
+ " movzbq %b0, %0; "
- : "=a" (res) : "m" (*lock), "a" (old), "q" (set));
+ : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
return res;
}
@@ -84,12 +179,38 @@
#define NGX_HAVE_ATOMIC_OPS 1
-typedef volatile uint32_t ngx_atomic_t;
+#if (NGX_PTR_SIZE == 8)
+typedef uint64_t ngx_atomic_int_t;
+#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
+#define NGX_CASXA "casxa"
+#else
+typedef uint32_t ngx_atomic_int_t;
+#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+#define NGX_CASXA "casa"
+#endif
+
+typedef volatile ngx_atomic_int_t ngx_atomic_t;
-static ngx_inline uint32_t ngx_atomic_inc(ngx_atomic_t *value)
+/*
+ * the "+r" means the general register used for both input and output.
+ *
+ * "casa [r1] 0x80, r2, r0" and
+ * "casxa [r1] 0x80, r2, r0" do the following:
+ *
+ * if ([r1] == r2) {
+ * swap(r0, [r1]);
+ * } else {
+ * r0 = [r1];
+ * }
+ *
+ * so "r0 == r2" means that the operation was successfull.
+ */
+
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_inc(ngx_atomic_t *value)
{
- uint32_t old, new, res;
+ ngx_atomic_int_t old, new, res;
old = *value;
@@ -100,9 +221,9 @@
__asm__ volatile (
- "casa [%1] 0x80, %2, %0"
+ NGX_CASXA " [%1] 0x80, %2, %0"
- : "+r" (res) : "r" (value), "r" (old));
+ : "+r" (res) : "r" (value), "r" (old) : "memory");
if (res == old) {
return new;
@@ -113,33 +234,155 @@
}
-static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock,
- ngx_atomic_t old,
- ngx_atomic_t set)
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_dec(ngx_atomic_t *value)
{
- uint32_t res = (uint32_t) set;
+ ngx_atomic_int_t old, new, res;
+
+ old = *value;
+
+ for ( ;; ) {
+
+ new = old - 1;
+ res = new;
+
+ __asm__ volatile (
+
+ NGX_CASXA " [%1] 0x80, %2, %0"
+
+ : "+r" (res) : "r" (value), "r" (old) : "memory");
+
+ if (res == old) {
+ return new;
+ }
+
+ old = res;
+ }
+}
+
+
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old, ngx_atomic_int_t set)
+{
+ __asm__ volatile (
+
+ NGX_CASXA " [%1] 0x80, %2, %0"
+
+ : "+r" (set) : "r" (lock), "r" (old) : "memory");
+
+ return (set == old);
+}
+
+
+#elif ( __ppc__ )
+
+#define NGX_HAVE_ATOMIC_OPS 1
+
+#if (NGX_PTR_SIZE == 8)
+typedef uint64_t ngx_atomic_int_t;
+#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
+#else
+#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+typedef uint32_t ngx_atomic_int_t;
+#endif
+
+typedef volatile ngx_atomic_int_t ngx_atomic_t;
+
+
+/*
+ * the ppc assembler treats ";" as comment, so we have to use "\n".
+ * the minus in "bne-" is a hint for the branch prediction unit that
+ * this branch is unlikely to be taken.
+ *
+ * the "=&r" means that no input registers can be used.
+ * the "=&b" means that the base registers can be used only, i.e. any register
+ * except r0. the r0 register can not be used in "addi r0, r0, 1".
+ * the "1b" means the nearest backward label "1" and the "1f" means
+ * the nearest forward label "1".
+ */
+
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_inc(ngx_atomic_t *value)
+{
+ ngx_atomic_int_t res;
__asm__ volatile (
- "casa [%1] 0x80, %2, %0"
+ "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */
+ /* and store reservation */
+ " addi %0, %0, 1 \n" /* add "1" to "res" */
+ " stwcx. %0, 0, %1 \n" /* store "res" into [value] if reservation */
+ /* is not cleared */
+ " bne- 1b \n" /* try again if reservation was cleared */
- : "+r" (res) : "r" (lock), "r" (old));
+ : "=&b" (res) : "r" (value) : "cc", "memory");
- return (res == old);
+ return res;
}
+
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_dec(ngx_atomic_t *value)
+{
+ ngx_atomic_int_t res;
+
+ __asm__ volatile (
+
+ "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */
+ /* and store reservation */
+ " addi %0, %0, -1 \n" /* sub "1" from "res" */
+ " stwcx. %0, 0, %1 \n" /* store "res" into [value] if reservation */
+ /* is not cleared */
+ " bne- 1b \n" /* try again if reservation was cleared */
+
+ : "=&b" (res) : "r" (value) : "cc", "memory");
+
+ return res;
+}
+
+
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old,
+ ngx_atomic_int_t set)
+{
+ ngx_atomic_int_t res, temp;
+
+ __asm__ volatile (
+
+ " li %0, 0 \n" /* preset "0" to "res" */
+ " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */
+ /* and store reservation */
+ " cmpw %1, %3 \n" /* compare "temp" and "old" */
+ " bne- 1f \n" /* not equal */
+ " stwcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */
+ /* is not cleared */
+ " bne- 1f \n" /* the reservation was cleared */
+ " li %0, 1 \n" /* set "1" to "res" */
+ "1: \n"
+
+ : "=&r" (res), "=&r" (temp)
+ : "r" (lock), "r" (old), "r" (set)
+ : "cc", "memory");
+
+ return res;
+}
+
+
#else
#define NGX_HAVE_ATOMIC_OPS 0
-typedef volatile uint32_t ngx_atomic_t;
+typedef uint32_t ngx_atomic_int_t;
+typedef volatile ngx_atomic_int_t ngx_atomic_t;
-#define ngx_atomic_inc(x) ++(*(x));
+#define ngx_atomic_inc(x) ++(*(x))
+#define ngx_atomic_dec(x) --(*(x))
-static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock,
- ngx_atomic_t old,
- ngx_atomic_t set)
+static ngx_inline ngx_atomic_int_t
+ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old,
+ ngx_atomic_int_t set)
{
+ *lock = set;
return 1;
}
diff --git a/src/os/unix/ngx_freebsd.h b/src/os/unix/ngx_freebsd.h
index 7a1e203..4e865a3 100644
--- a/src/os/unix/ngx_freebsd.h
+++ b/src/os/unix/ngx_freebsd.h
@@ -9,7 +9,7 @@
ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
+ off_t limit);
extern int ngx_freebsd_kern_osreldate;
extern int ngx_freebsd_hw_ncpu;
diff --git a/src/os/unix/ngx_linux.h b/src/os/unix/ngx_linux.h
index 4a8f8f3..e871ba9 100644
--- a/src/os/unix/ngx_linux.h
+++ b/src/os/unix/ngx_linux.h
@@ -8,11 +8,8 @@
#define _NGX_LINUX_H_INCLUDED_
-ngx_int_t ngx_init_setproctitle(ngx_log_t *log);
-void ngx_setproctitle(char *title);
-
ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
+ off_t limit);
extern int ngx_linux_rtsig_max;
diff --git a/src/os/unix/ngx_linux_init.c b/src/os/unix/ngx_linux_init.c
index 9c1c847..7f7be89 100644
--- a/src/os/unix/ngx_linux_init.c
+++ b/src/os/unix/ngx_linux_init.c
@@ -28,7 +28,8 @@
};
-ngx_int_t ngx_os_init(ngx_log_t *log)
+ngx_int_t
+ngx_os_init(ngx_log_t *log)
{
int name[2];
size_t len;
@@ -37,28 +38,29 @@
name[0] = CTL_KERN;
name[1] = KERN_OSTYPE;
len = sizeof(ngx_linux_kern_ostype);
- if (sysctl(name, sizeof(name), ngx_linux_kern_ostype, &len, NULL, 0)
- == -1) {
+
+ if (sysctl(name, 2, ngx_linux_kern_ostype, &len, NULL, 0) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"sysctl(KERN_OSTYPE) failed");
return NGX_ERROR;
}
- name[0] = CTL_KERN;
+ /* name[0] = CTL_KERN; */
name[1] = KERN_OSRELEASE;
len = sizeof(ngx_linux_kern_osrelease);
- if (sysctl(name, sizeof(name), ngx_linux_kern_osrelease, &len, NULL, 0)
- == -1) {
+
+ if (sysctl(name, 2, ngx_linux_kern_osrelease, &len, NULL, 0) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"sysctl(KERN_OSRELEASE) failed");
return NGX_ERROR;
}
- name[0] = CTL_KERN;
+ /* name[0] = CTL_KERN; */
name[1] = KERN_RTSIGMAX;
len = sizeof(ngx_linux_rtsig_max);
- if (sysctl(name, sizeof(name), &ngx_linux_rtsig_max, &len, NULL, 0) == -1) {
+
+ if (sysctl(name, 2, &ngx_linux_rtsig_max, &len, NULL, 0) == -1) {
err = ngx_errno;
if (err != NGX_ENOTDIR) {
@@ -78,7 +80,8 @@
}
-void ngx_os_status(ngx_log_t *log)
+void
+ngx_os_status(ngx_log_t *log)
{
ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %s %s",
ngx_linux_kern_ostype, ngx_linux_kern_osrelease);
diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h
index 42fc886..e39aab0 100644
--- a/src/os/unix/ngx_os.h
+++ b/src/os/unix/ngx_os.h
@@ -20,7 +20,7 @@
typedef ssize_t (*ngx_recv_chain_pt)(ngx_connection_t *c, ngx_chain_t *in);
typedef ssize_t (*ngx_send_pt)(ngx_connection_t *c, u_char *buf, size_t size);
typedef ngx_chain_t *(*ngx_send_chain_pt)(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
+ off_t limit);
typedef struct {
ngx_recv_pt recv;
@@ -44,7 +44,7 @@
ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size);
ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
+ off_t limit);
extern ngx_os_io_t ngx_os_io;
diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h
index 12703b3..995e93c 100644
--- a/src/os/unix/ngx_process.h
+++ b/src/os/unix/ngx_process.h
@@ -49,8 +49,7 @@
#define ngx_log_pid ngx_pid
ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle,
- ngx_spawn_proc_pt proc, void *data,
- char *name, ngx_int_t respawn);
+ ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn);
ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx);
void ngx_process_get_status(void);
void ngx_debug_point(void);
@@ -63,6 +62,12 @@
#endif
+#if !defined(ngx_setproctitle)
+ngx_int_t ngx_init_setproctitle(ngx_log_t *log);
+void ngx_setproctitle(char *title);
+#endif
+
+
extern int ngx_argc;
extern char **ngx_argv;
extern char **ngx_os_argv;
diff --git a/src/os/unix/ngx_setproctitle.c b/src/os/unix/ngx_setproctitle.c
index 2e41108..6c95cdf 100644
--- a/src/os/unix/ngx_setproctitle.c
+++ b/src/os/unix/ngx_setproctitle.c
@@ -30,9 +30,10 @@
static char *ngx_os_argv_last;
-ngx_int_t ngx_init_setproctitle(ngx_log_t *log)
+ngx_int_t
+ngx_init_setproctitle(ngx_log_t *log)
{
- char *p;
+ u_char *p;
size_t size;
ngx_uint_t i;
@@ -60,8 +61,8 @@
size = ngx_strlen(environ[i]) + 1;
ngx_os_argv_last = environ[i] + size;
- ngx_cpystrn(p, environ[i], size);
- environ[i] = p;
+ ngx_cpystrn(p, (u_char *) environ[i], size);
+ environ[i] = (char *) p;
p += size;
}
}
@@ -72,7 +73,8 @@
}
-void ngx_setproctitle(char *title)
+void
+ngx_setproctitle(char *title)
{
u_char *p;
@@ -131,13 +133,16 @@
#elif !defined(ngx_setproctitle)
-ngx_int_t ngx_init_setproctitle(ngx_log_t *log)
+ngx_int_t
+ngx_init_setproctitle(ngx_log_t *log)
{
return NGX_OK;
}
-void ngx_setproctitle(char *title)
+void
+ngx_setproctitle(char *title)
{
+ return;
}
#endif
diff --git a/src/os/unix/ngx_solaris.h b/src/os/unix/ngx_solaris.h
index 705cd57..44ce796 100644
--- a/src/os/unix/ngx_solaris.h
+++ b/src/os/unix/ngx_solaris.h
@@ -8,12 +8,8 @@
#define _NGX_SOLARIS_H_INCLUDED_
-ngx_int_t ngx_init_setproctitle(ngx_log_t *log);
-void ngx_setproctitle(char *title);
-
-
ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
+ off_t limit);
#endif /* _NGX_SOLARIS_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_atomic.h b/src/os/win32/ngx_atomic.h
index b4915d0..7022bfa 100644
--- a/src/os/win32/ngx_atomic.h
+++ b/src/os/win32/ngx_atomic.h
@@ -14,8 +14,13 @@
#define NGX_HAVE_ATOMIC_OPS 1
+typedef uint32_t ngx_atomic_int_t;
+typedef volatile ngx_atomic_int_t ngx_atomic_t;
+#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+
#define ngx_atomic_inc(p) InterlockedIncrement((long *) p)
+#define ngx_atomic_dec(p) InterlockedDecrement((long *) p)
#if defined( __WATCOMC__ ) || defined( __BORLANDC__ ) || ( _MSC_VER >= 1300 )
diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h
index 7c3bcd5..5bdf91f 100644
--- a/src/os/win32/ngx_win32_config.h
+++ b/src/os/win32/ngx_win32_config.h
@@ -111,7 +111,6 @@
typedef uint32_t in_addr_t;
typedef u_short in_port_t;
typedef int sig_atomic_t;
-typedef uint32_t ngx_atomic_t;
#define NGX_SIZE_T_LEN sizeof("-2147483648") - 1