# HG changeset patch # User Igor Sysoev # Date 1109019600 -10800 # Node ID 41ccba1aba45f7d7af0990fab0ae98a3693d222a # Parent 4d8e7a81b3a03e911b32c7f40ebac1c019fdae31 nginx 0.1.21 *) 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/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,14 @@ + +Changes with nginx 0.1.21 22 Feb 2005 + + *) Bugfix: the ngx_http_stub_status_module showed incorrect statictics + 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. + Changes with nginx 0.1.20 17 Feb 2005 diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,3 +1,15 @@ + +Изменения в nginx 0.1.21 22.02.2005 + + *) Исправление: модуль ngx_http_stub_status_module показывал неверную + статистику при использовании метода rtsig или при использовании + нескольких рабочих процессов на SMP машине. + + *) Исправление: nginx не собирался компилятором icc под Линуксом или + если библиотека zlib-1.2.x собиралась из исходных текстов. + + *) Исправление: nginx не собирался под NetBSD 2.0. + Изменения в nginx 0.1.20 17.02.2005 diff --git a/auto/cc/icc b/auto/cc/icc --- a/auto/cc/icc +++ b/auto/cc/icc @@ -2,7 +2,7 @@ # Copyright (C) Igor Sysoev -# Intel C++ compiler 7.1, 8.0 +# Intel C++ compiler 7.1, 8.0, 8.1 # optimizations @@ -57,7 +57,7 @@ fi CFLAGS="$CFLAGS -w1" #CFLAGS="$CFLAGS -w2" -# disable the ICC 8.0 errors: +# disable the ICC 8.1 errors: # error #181: argument is incompatible with corresponding format # string conversion # error #269: invalid format string conversion diff --git a/auto/cc/name b/auto/cc/name --- a/auto/cc/name +++ b/auto/cc/name @@ -29,7 +29,7 @@ if [ $CC = bcc32 ]; then echo " using Borland C++ compiler" else -if `$CC -v 2>&1 | grep '^gcc version' 2>&1 >/dev/null`; then +if `$CC -v 2>&1 | grep 'gcc version' 2>&1 >/dev/null`; then NGX_CC_NAME=gcc echo " using GNU C compiler" diff --git a/auto/install b/auto/install --- a/auto/install +++ b/auto/install @@ -4,38 +4,41 @@ cat << END >> $NGX_MAKEFILE -install: - test -d $NGX_PREFIX || mkdir -p $NGX_PREFIX +install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} + test -d "$NGX_PREFIX" || mkdir -p "$NGX_PREFIX" - test -d `dirname $NGX_SBIN_PATH` || mkdir -p `dirname $NGX_SBIN_PATH` - test ! -f $NGX_SBIN_PATH || mv $NGX_SBIN_PATH $NGX_SBIN_PATH.old - cp $NGX_OBJS/nginx $NGX_SBIN_PATH + test -d "`dirname \"$NGX_SBIN_PATH\"`" \ + || mkdir -p "`dirname \"$NGX_SBIN_PATH\"`" + test ! -f "$NGX_SBIN_PATH" || mv "$NGX_SBIN_PATH" "$NGX_SBIN_PATH.old" + cp $NGX_OBJS/nginx "$NGX_SBIN_PATH" - test -d `dirname $NGX_CONF_PATH` || mkdir -p `dirname $NGX_CONF_PATH` + test -d "`dirname \"$NGX_CONF_PATH\"`" \ + || mkdir -p "`dirname \"$NGX_CONF_PATH\"`" - cp conf/koi-win `dirname $NGX_CONF_PATH` + cp conf/koi-win "`dirname \"$NGX_CONF_PATH\"`" - test -f `dirname $NGX_CONF_PATH`/mime.types || \ - cp conf/mime.types `dirname $NGX_CONF_PATH`/mime.types - cp conf/mime.types `dirname $NGX_CONF_PATH`/mime.types.default + test -f "`dirname \"$NGX_CONF_PATH\"`/mime.types" || \ + cp conf/mime.types "`dirname \"$NGX_CONF_PATH\"`/mime.types" + cp conf/mime.types "`dirname \"$NGX_CONF_PATH\"`/mime.types.default" - test -f $NGX_CONF_PATH || cp conf/nginx.conf $NGX_CONF_PATH - cp conf/nginx.conf `dirname $NGX_CONF_PATH`/nginx.conf.default + test -f "$NGX_CONF_PATH" || cp conf/nginx.conf "$NGX_CONF_PATH" + cp conf/nginx.conf "`dirname \"$NGX_CONF_PATH\"`/nginx.conf.default" - test -d `dirname $NGX_PID_PATH` || mkdir -p `dirname $NGX_PID_PATH` + test -d "`dirname \"$NGX_PID_PATH\"`" \ + || mkdir -p "`dirname \"$NGX_PID_PATH\"`" - test -d `dirname $NGX_HTTP_LOG_PATH` || \ - mkdir -p `dirname $NGX_HTTP_LOG_PATH` + test -d "`dirname \"$NGX_HTTP_LOG_PATH\"`" || \ + mkdir -p "`dirname \"$NGX_HTTP_LOG_PATH\"`" - test -d $NGX_PREFIX/html || cp -r html $NGX_PREFIX + test -d "$NGX_PREFIX/html" || cp -r html "$NGX_PREFIX" END if test -n "$NGX_ERROR_LOG_PATH"; then cat << END >> $NGX_MAKEFILE - test -d `dirname $NGX_ERROR_LOG_PATH` || \ - mkdir -p `dirname $NGX_ERROR_LOG_PATH` + test -d "`dirname \"$NGX_ERROR_LOG_PATH\"`" || \ + mkdir -p "`dirname \"$NGX_ERROR_LOG_PATH\"`" END fi diff --git a/auto/lib/md5/conf b/auto/lib/md5/conf --- a/auto/lib/md5/conf +++ b/auto/lib/md5/conf @@ -44,7 +44,7 @@ if [ $MD5 != NONE ]; then else - if [ $NGX_PLATFORM != win32 ]; then + if [ "$NGX_PLATFORM" != win32 ]; then MD5=NO # Solaris 8/9 diff --git a/auto/lib/md5/make b/auto/lib/md5/make --- a/auto/lib/md5/make +++ b/auto/lib/md5/make @@ -25,7 +25,7 @@ esac done=NO -case $NGX_PLATFORM in +case "$NGX_PLATFORM" in win32) cp auto/lib/md5/$ngx_makefile $MD5 diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf --- a/auto/lib/openssl/conf +++ b/auto/lib/openssl/conf @@ -24,7 +24,7 @@ if [ $OPENSSL != NONE ]; then else - if [ $NGX_PLATFORM != win32 ]; then + if [ "$NGX_PLATFORM" != win32 ]; then OPENSSL=NO ngx_feature="OpenSSL library" diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make --- a/auto/lib/openssl/make +++ b/auto/lib/openssl/make @@ -2,7 +2,7 @@ # Copyright (C) Igor Sysoev -case $NGX_PLATFORM in +case "$NGX_PLATFORM" in *) echo "$OPENSSL/libssl.a:" >> $MAKEFILE echo " cd $OPENSSL \\" >> $MAKEFILE diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf --- a/auto/lib/pcre/conf +++ b/auto/lib/pcre/conf @@ -42,7 +42,7 @@ if [ $PCRE != NONE ]; then else - if [ $NGX_PLATFORM != win32 ]; then + if [ "$NGX_PLATFORM" != win32 ]; then PCRE=NO # FreeBSD PCRE port requires --with-cc-opt="-I /usr/local/include" diff --git a/auto/lib/pcre/make b/auto/lib/pcre/make --- a/auto/lib/pcre/make +++ b/auto/lib/pcre/make @@ -22,7 +22,7 @@ case "$NGX_CC_NAME" in esac -case $NGX_PLATFORM in +case "$NGX_PLATFORM" in win32) cp auto/lib/pcre/patch.pcre.in $PCRE diff --git a/auto/lib/zlib/conf b/auto/lib/zlib/conf --- a/auto/lib/zlib/conf +++ b/auto/lib/zlib/conf @@ -21,6 +21,7 @@ if [ $ZLIB != NONE ]; then CORE_LIBS="$CORE_LIBS $ZLIB/deflate.o" CORE_LIBS="$CORE_LIBS $ZLIB/trees.o" CORE_LIBS="$CORE_LIBS $ZLIB/zutil.o" + CORE_LIBS="$CORE_LIBS $ZLIB/compress.o" if [ $ZLIB_ASM != NO ]; then CORE_LIBS="$CORE_LIBS $ZLIB/match.o" @@ -37,7 +38,7 @@ if [ $ZLIB != NONE ]; then else - if [ $NGX_PLATFORM != win32 ]; then + if [ "$NGX_PLATFORM" != win32 ]; then ZLIB=NO # FreeBSD, Solaris, Linux diff --git a/auto/lib/zlib/make b/auto/lib/zlib/make --- a/auto/lib/zlib/make +++ b/auto/lib/zlib/make @@ -26,7 +26,7 @@ esac done=NO -case $NGX_PLATFORM in +case "$NGX_PLATFORM" in win32) cp auto/lib/zlib/$ngx_makefile $ZLIB diff --git a/auto/lib/zlib/makefile.bcc b/auto/lib/zlib/makefile.bcc --- a/auto/lib/zlib/makefile.bcc +++ b/auto/lib/zlib/makefile.bcc @@ -5,7 +5,8 @@ CFLAGS = -q -O2 -tWM $(CPU_OPT) zlib.lib: - bcc32 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c + bcc32 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c \ + compress.c tlib zlib.lib +adler32.obj +crc32.obj +deflate.obj \ - +trees.obj +zutil.obj + +trees.obj +zutil.obj +compress.obj diff --git a/auto/lib/zlib/makefile.msvc b/auto/lib/zlib/makefile.msvc --- a/auto/lib/zlib/makefile.msvc +++ b/auto/lib/zlib/makefile.msvc @@ -5,7 +5,7 @@ CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) zlib.lib: - cl -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c + cl -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c compress.c link -lib -out:zlib.lib adler32.obj crc32.obj deflate.obj \ - trees.obj zutil.obj + trees.obj zutil.obj compress.obj diff --git a/auto/lib/zlib/makefile.owc b/auto/lib/zlib/makefile.owc --- a/auto/lib/zlib/makefile.owc +++ b/auto/lib/zlib/makefile.owc @@ -5,5 +5,5 @@ CFLAGS = -zq -bt=nt -ot -op -oi -oe -s -bm $(CPU_OPT) zlib.lib: - wcl386 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c - wlib -n zlib.lib adler32.obj crc32.obj deflate.obj trees.obj zutil.obj + wcl386 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c compress.c + wlib -n zlib.lib adler32.obj crc32.obj deflate.obj trees.obj zutil.obj compress.obj diff --git a/auto/os/conf b/auto/os/conf --- a/auto/os/conf +++ b/auto/os/conf @@ -12,11 +12,12 @@ if test -z "$NGX_PLATFORM"; then echo " + $NGX_SYSTEM $NGX_RELEASE $NGX_MACHINE" NGX_PLATFORM="$NGX_SYSTEM:$NGX_RELEASE:$NGX_MACHINE"; + else echo "building for $NGX_PLATFORM" fi -case $NGX_PLATFORM in +case "$NGX_PLATFORM" in FreeBSD:* | DragonFly:*) . auto/os/freebsd @@ -43,7 +44,7 @@ case $NGX_PLATFORM in esac -case $NGX_MACHINE in +case "$NGX_MACHINE" in i386|i686|i86pc|amd64) have=NGX_HAVE_NONALIGNED . auto/have @@ -52,7 +53,7 @@ case $NGX_MACHINE in esac -if [ $NGX_PLATFORM != win32 ]; then +if [ "$NGX_PLATFORM" != win32 ]; then NGX_USER=${NGX_USER:-nobody} @@ -77,6 +78,24 @@ if [ $NGX_PLATFORM != win32 ]; then fi + ngx_feature="poll()" + ngx_feature_name= + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_libs= + ngx_feature_test="int n, dp; struct pollfd pl; + dp = 0; + pl.fd = 0; + pl.events = 0; + pl.revents = 0; + n = poll(&pl, 1, 0)" + . auto/feature + + if [ $ngx_found = no ]; then + EVENT_POLL=NONE + fi + + ngx_feature="/dev/poll" ngx_feature_name="NGX_HAVE_DEVPOLL" ngx_feature_run=no @@ -124,14 +143,22 @@ if [ $NGX_PLATFORM != win32 ]; then fi fi - if [ NGX_SYSTEM != "NetBSD" ]; then + if [ "$NGX_SYSTEM" = "NetBSD" ]; then # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t" + + cat << END >> $NGX_AUTO_CONFIG_H + +#define NGX_KQUEUE_UDATA_T + +END + + else cat << END >> $NGX_AUTO_CONFIG_H #define NGX_KQUEUE_UDATA_T (void *) END - fi + fi fi diff --git a/auto/os/linux b/auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -18,7 +18,7 @@ EVENT_MODULES="$EVENT_MODULES" ngx_spacer=' ' -CC_AUX_FLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" +CC_AUX_FLAGS="$CC_AUX_FLAGS -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" # Linux kernel version diff --git a/auto/os/solaris b/auto/os/solaris --- a/auto/os/solaris +++ b/auto/os/solaris @@ -20,10 +20,10 @@ CORE_LIBS="$CORE_LIBS -lsocket -lnsl -lr # Solaris's make does not support a blank line between target and rules ngx_spacer= -CC_AUX_FLAGS="-D_FILE_OFFSET_BITS=64 -lrt" +CC_AUX_FLAGS="$CC_AUX_FLAGS -D_FILE_OFFSET_BITS=64 -lrt" -case $NGX_PLATFORM in +case "$NGX_PLATFORM" in *:sun4u) # "-mcpu=v9" enables the "casa" assembler instruction diff --git a/auto/summary b/auto/summary --- a/auto/summary +++ b/auto/summary @@ -118,22 +118,22 @@ fi cat << END - nginx path prefix: $NGX_PREFIX - nginx binary file: $NGX_SBIN_PATH - nginx configuration file: $NGX_CONF_PATH - nginx pid file: $NGX_PID_PATH + nginx path prefix: "$NGX_PREFIX" + nginx binary file: "$NGX_SBIN_PATH" + nginx configuration file: "$NGX_CONF_PATH" + nginx pid file: "$NGX_PID_PATH" END if test -n "$NGX_ERROR_LOG_PATH"; then - echo " nginx error log file: $NGX_ERROR_LOG_PATH" + echo " nginx error log file: \"$NGX_ERROR_LOG_PATH\"" else echo " nginx logs errors to stderr" fi cat << END - nginx http access log file: $NGX_HTTP_LOG_PATH - nginx http client request body temporary files: $NGX_HTTP_CLIENT_TEMP_PATH - nginx http proxy temporary files: $NGX_HTTP_PROXY_TEMP_PATH - nginx http fastcgi temporary files: $NGX_HTTP_FASTCGI_TEMP_PATH + nginx http access log file: "$NGX_HTTP_LOG_PATH" + nginx http client request body temporary files: "$NGX_HTTP_CLIENT_TEMP_PATH" + nginx http proxy temporary files: "$NGX_HTTP_PROXY_TEMP_PATH" + nginx http fastcgi temporary files: "$NGX_HTTP_FASTCGI_TEMP_PATH" END diff --git a/auto/threads b/auto/threads --- a/auto/threads +++ b/auto/threads @@ -9,7 +9,7 @@ case $USE_THREADS in CORE_DEPS="$CORE_DEPS $FREEBSD_RFORK_DEPS" CORE_SRCS="$CORE_SRCS $FREEBSD_RFORK_SRCS" - case $NGX_PLATFORM in + case "$NGX_PLATFORM" in *:i386) if [ \( $version -gt 500000 -a $version -lt 501000 \) \ -o $version -lt 491000 ] @@ -42,7 +42,7 @@ case $USE_THREADS in ;; libc_r) - case $NGX_PLATFORM in + case "$NGX_PLATFORM" in FreeBSD:[34]*) have=NGX_THREADS . auto/have CFLAGS="$CFLAGS -pthread" diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -5,23 +5,21 @@ have=NGX_HAVE_UNIX_DOMAIN . auto/have +# STUB CC_WARN= ngx_fmt_collect=yes + # C types ngx_type="int"; . auto/types/sizeof -#ngx_formats="%d"; . auto/fmt/fmt ngx_type="long"; . auto/types/sizeof -#ngx_formats="%ld"; . auto/fmt/fmt ngx_type="long long"; . auto/types/sizeof -#ngx_formats="%lld %qd"; . auto/fmt/fmt ngx_type="void *"; . auto/types/sizeof; ngx_ptr_size=$ngx_size -#ngx_fmt_name=PTR_FMT; -#eval ngx_formats=\${ngx_${ngx_ptr_size}_fmt}; . auto/fmt/ptrfmt +ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_size; . auto/types/value # POSIX types diff --git a/conf/nginx.conf b/conf/nginx.conf --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -15,7 +15,10 @@ http { include conf/mime.types; default_type application/octet-stream; - sendfile on; + sendfile on; + # tcp_nodelay on; + + # keepalive_timeout 0; #gzip on; diff --git a/src/core/nginx.h b/src/core/nginx.h --- 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 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -114,7 +114,7 @@ struct ngx_connection_s { 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 --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -8,11 +8,12 @@ #include -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 @@ ssize_t ngx_write_chain_to_temp_file(ngx } -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_int_t ngx_create_temp_file(ngx_file_ 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 @@ ngx_int_t ngx_create_temp_file(ngx_file_ err = ngx_errno; if (err == NGX_EEXIST) { - num = ngx_next_temp_number(1); + n = ngx_next_temp_number(1); continue; } @@ -101,7 +103,8 @@ ngx_int_t ngx_create_temp_file(ngx_file_ } -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 @@ void ngx_create_hashed_filename(ngx_file } -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 @@ ngx_int_t ngx_create_path(ngx_file_t *fi } -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 @@ ngx_uint_t ngx_next_temp_number(ngx_uint } -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 @@ char *ngx_conf_set_path_slot(ngx_conf_t } -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_add_path(ngx_conf_t *cf, n } -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 --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -55,14 +55,14 @@ typedef struct { 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 --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -87,15 +87,9 @@ void ngx_log_error_core(ngx_uint_t level 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 --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -47,7 +47,7 @@ struct ngx_log_s { 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 --- a/src/core/ngx_radix_tree.c +++ b/src/core/ngx_radix_tree.c @@ -40,8 +40,8 @@ ngx_radix_tree_create(ngx_pool_t *pool, } /* - * 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 --- 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_insert(ngx_rbtree_t **ro } -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 @@ void ngx_rbtree_delete(ngx_rbtree_t **ro } -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_left_r } -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 --- a/src/core/ngx_rbtree.h +++ b/src/core/ngx_rbtree.h @@ -24,13 +24,13 @@ struct ngx_rbtree_s { 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 --- a/src/core/ngx_spinlock.c +++ b/src/core/ngx_spinlock.c @@ -8,6 +8,10 @@ #include +/* + * 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 --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -8,7 +8,8 @@ #include -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_cpystrn(u_char *dst, u_char } -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 @@ u_char *ngx_pstrdup(ngx_pool_t *pool, ng * %[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 @@ u_char *ngx_pstrdup(ngx_pool_t *pool, ng * * TODO: * %M ngx_msec_t - * %A ngx_atomic_t * * reserved: * %t ptrdiff_t @@ -72,7 +74,8 @@ u_char *ngx_pstrdup(ngx_pool_t *pool, ng */ -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_sprintf(u_char *buf, const c } -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_snprintf(u_char *buf, size_t } -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 @@ u_char *ngx_vsnprintf(u_char *buf, size_ 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 @@ u_char *ngx_vsnprintf(u_char *buf, size_ width = 0; sign = 1; hexadecimal = 0; + max_width = 0; p = temp + NGX_INT64_LEN; @@ -154,7 +160,7 @@ u_char *ngx_vsnprintf(u_char *buf, size_ continue; case 'm': - width = NGX_INT_T_LEN; + max_width = 1; fmt++; continue; @@ -228,6 +234,11 @@ u_char *ngx_vsnprintf(u_char *buf, size_ } 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 @@ u_char *ngx_vsnprintf(u_char *buf, size_ } 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 @@ u_char *ngx_vsnprintf(u_char *buf, size_ * 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 @@ u_char *ngx_vsnprintf(u_char *buf, size_ } -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_rstrncmp(u_char *s1, u_cha } -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_rstrncasecmp(u_char *s1, u } -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_atoi(u_char *line, size_t } -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 @@ ngx_int_t ngx_hextoi(u_char *line, size_ } -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_md5_text(u_char *text, u_char * } -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 @@ void ngx_encode_base64(ngx_str_t *dst, n } -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 @@ ngx_int_t ngx_decode_base64(ngx_str_t *d } -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 @@ uintptr_t ngx_escape_uri(u_char *dst, u_ 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 @@ uintptr_t ngx_escape_uri(u_char *dst, u_ { 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 --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -98,7 +98,7 @@ ngx_int_t ngx_decode_base64(ngx_str_t *d #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 --- a/src/event/modules/ngx_rtsig_module.c +++ b/src/event/modules/ngx_rtsig_module.c @@ -701,18 +701,18 @@ static ngx_int_t ngx_rtsig_process_overf 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 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -34,21 +34,21 @@ static char *ngx_event_init_conf(ngx_cyc 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 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -7,14 +7,14 @@ #include #include #include -#include 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 @@ void ngx_event_accept(ngx_event_t *ev) /* * 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 @@ void ngx_event_accept(ngx_event_t *ev) } #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 @@ void ngx_event_accept(ngx_event_t *ev) } #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 @@ void ngx_event_accept(ngx_event_t *ev) 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 @@ void ngx_event_accept(ngx_event_t *ev) } -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_trylock_accept_mutex(ngx_c } -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_enable_accept_events(ngx_c } -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 @@ ngx_int_t ngx_disable_accept_events(ngx_ } -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 void ngx_close_accepted_socket(ng } -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 --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -18,7 +18,8 @@ ngx_thread_volatile ngx_rbtree_t *ngx_e 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_int_t ngx_event_timer_init(ngx_log_t } -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 @@ ngx_msec_t ngx_event_find_timer(void) } -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 --- 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_thread_volatile ngx_rbtree_t 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_del_tim } -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 @@ static ngx_inline void ngx_event_add_tim /* * 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 --- 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_header_filter_pt 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 @@ static ngx_int_t ngx_http_range_header_f 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 @@ static ngx_int_t ngx_http_range_header_f 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 @@ static ngx_int_t ngx_http_range_header_f 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 @@ static ngx_int_t ngx_http_range_header_f } 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 @@ static ngx_int_t ngx_http_range_header_f } 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 @@ static ngx_int_t ngx_http_range_header_f 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_header_f } -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 @@ static ngx_int_t ngx_http_range_body_fil 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_body_fil } -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_header_f } -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 --- a/src/http/modules/ngx_http_stub_status_module.c +++ b/src/http/modules/ngx_http_stub_status_module.c @@ -102,15 +102,15 @@ static ngx_int_t ngx_http_status_handler 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 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -117,7 +117,8 @@ ngx_http_header_t ngx_http_headers_out[ }; -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 @@ static ngx_int_t ngx_http_header_filter( } } - /* 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 @@ static ngx_int_t ngx_http_header_filter( 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 @@ static ngx_int_t ngx_http_header_filter( 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 @@ static ngx_int_t ngx_http_header_filter( 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 @@ static ngx_int_t ngx_http_header_filter( 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 @@ static ngx_int_t ngx_http_header_filter( 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 @@ static ngx_int_t ngx_http_header_filter( 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 @@ static ngx_int_t ngx_http_header_filter( } 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( } -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 --- a/src/http/ngx_http_log_handler.c +++ b/src/http/ngx_http_log_handler.c @@ -135,7 +135,8 @@ static ngx_str_t ngx_http_combined_fmt = 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_http_log_op_name_t ngx_http_log_fmt_ { 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 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -138,6 +138,7 @@ void ngx_http_init_connection(ngx_connec if (ngx_accept_mutex) { if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + ngx_http_close_connection(c); return; } @@ -145,11 +146,15 @@ void ngx_http_init_connection(ngx_connec 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 @@ void ngx_http_init_connection(ngx_connec #endif #if (NGX_STAT_STUB) - (*ngx_stat_reading)++; + ngx_atomic_inc(ngx_stat_reading); #endif } @@ -205,7 +210,7 @@ static void ngx_http_init_request(ngx_ev 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 @@ static void ngx_http_init_request(ngx_ev 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 @@ static void ngx_http_init_request(ngx_ev 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 @@ static void ngx_http_init_request(ngx_ev } #if (NGX_STAT_STUB) - (*ngx_stat_reading)--; + ngx_atomic_dec(ngx_stat_reading); #endif c->data = r; @@ -427,9 +432,9 @@ static void ngx_http_init_request(ngx_ev 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 @@ static void ngx_http_process_request_hea } #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 @@ void ngx_http_close_request(ngx_http_req #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 @@ void ngx_http_close_connection(ngx_conne #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 --- a/src/os/unix/ngx_atomic.h +++ b/src/os/unix/ngx_atomic.h @@ -12,11 +12,104 @@ #include -#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 @@ typedef volatile uint32_t ngx_atomic_t; #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 @@ static ngx_inline uint32_t ngx_atomic_cm #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,36 @@ static ngx_inline uint32_t ngx_atomic_in __asm__ volatile ( - "casa [%1] 0x80, %2, %0" + NGX_CASXA " [%1] 0x80, %2, %0" + + : "+r" (res) : "r" (value), "r" (old) : "memory"); + + if (res == old) { + return new; + } + + old = res; + } +} + - : "+r" (res) : "r" (value), "r" (old)); +static ngx_inline ngx_atomic_int_t +ngx_atomic_dec(ngx_atomic_t *value) +{ + 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; @@ -113,33 +261,128 @@ static ngx_inline uint32_t ngx_atomic_in } -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 = (uint32_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 */ + + : "=&b" (res) : "r" (value) : "cc", "memory"); + + 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"); - : "+r" (res) : "r" (lock), "r" (old)); + 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 ( - return (res == old); + " 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 --- 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 --- 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 --- a/src/os/unix/ngx_linux_init.c +++ b/src/os/unix/ngx_linux_init.c @@ -28,7 +28,8 @@ ngx_os_io_t ngx_os_io = { }; -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 @@ ngx_int_t ngx_os_init(ngx_log_t *log) 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 @@ ngx_int_t ngx_os_init(ngx_log_t *log) } -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 --- a/src/os/unix/ngx_os.h +++ b/src/os/unix/ngx_os.h @@ -20,7 +20,7 @@ typedef ssize_t (*ngx_recv_pt)(ngx_conne 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_unix_recv(ngx_connection_t * 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 --- a/src/os/unix/ngx_process.h +++ b/src/os/unix/ngx_process.h @@ -49,8 +49,7 @@ typedef struct { #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 @@ void ngx_debug_point(void); #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 --- a/src/os/unix/ngx_setproctitle.c +++ b/src/os/unix/ngx_setproctitle.c @@ -30,9 +30,10 @@ extern char **environ; 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 @@ ngx_int_t ngx_init_setproctitle(ngx_log 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 @@ ngx_int_t ngx_init_setproctitle(ngx_log } -void ngx_setproctitle(char *title) +void +ngx_setproctitle(char *title) { u_char *p; @@ -131,13 +133,16 @@ void ngx_setproctitle(char *title) #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 --- 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_ */