# HG changeset patch # User Igor Sysoev # Date 1166907600 -10800 # Node ID 6eb1e38f0f1f8e97ac5a3912edb6eda75722b0b2 # Parent aa9c0062124d777154ec071c089269e8640618f8 nginx 0.5.5 *) Change: the -v switch does not show compiler information any more. *) Feature: the -V switch. *) Feature: the "worker_rlimit_core" directive supports size in K, M, and G. *) Bugfix: the nginx.pm module now could be installed by an unprivileged user. *) Bugfix: a segmentation fault might occur if the $r->request_body or $r->request_body_file methods were used. *) Bugfix: the ppc platform specific bugs. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,22 @@ +Changes with nginx 0.5.5 24 Dec 2006 + + *) Change: the -v switch does not show compiler information any more. + + *) Feature: the -V switch. + + *) Feature: the "worker_rlimit_core" directive supports size in K, M, + and G. + + *) Bugfix: the nginx.pm module now could be installed by an + unprivileged user. + + *) Bugfix: a segmentation fault might occur if the $r->request_body or + $r->request_body_file methods were used. + + *) Bugfix: the ppc platform specific bugs. + + Changes with nginx 0.5.4 15 Dec 2006 *) Feature: the "perl" directive may be used inside the "limit_except" diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,22 @@ +Изменения в nginx 0.5.5 24.12.2006 + + *) Изменение: ключ -v больше не выводит информацию о компиляторе. + + *) Добавление: ключ -V. + + *) Добавление: директива worker_rlimit_core поддерживает указание + размера в K, M и G. + + *) Исправление: модуль nginx.pm теперь может устанавливаться + непривилегированным пользователем. + + *) Исправление: при использовании методов $r->request_body или + $r->request_body_file мог произойти segmentation fault. + + *) Исправление: ошибок, специфичных для платформы ppc. + + Изменения в nginx 0.5.4 15.12.2006 *) Добавление: директиву perl можно использовать внутри блока diff --git a/auto/cc/name b/auto/cc/name --- a/auto/cc/name +++ b/auto/cc/name @@ -2,7 +2,25 @@ # Copyright (C) Igor Sysoev -echo $ngx_n "checking for C compiler ...$ngx_c" +if [ "$NGX_PLATFORM" != win32 ]; then + + ngx_feature="C compiler" + ngx_feature_name= + ngx_feature_run=yes + ngx_feature_incs= + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test= + . auto/feature + + if [ $ngx_found = no ]; then + echo + echo $0: error: C compiler $CC is not found + echo + exit 1 + fi + +fi if [ "$CC" = cl ]; then @@ -11,51 +29,50 @@ if [ "$CC" = cl ]; then >/dev/null 2>&1`; then NGX_CC_NAME=msvc7 - echo " Microsoft Visual C++ 7 compiler" + echo " + using Microsoft Visual C++ 7 compiler" else NGX_CC_NAME=msvc - echo " Microsoft Visual C++ compiler" + echo " + using Microsoft Visual C++ compiler" fi else if [ "$CC" = wcl386 ]; then NGX_CC_NAME=owc - echo " Open Watcom C compiler" + echo " + using Open Watcom C compiler" else if [ "$CC" = bcc32 ]; then NGX_CC_NAME=bcc - echo " Borland C++ compiler" + echo " + using Borland C++ compiler" else if `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then NGX_CC_NAME=gcc - echo " GNU C compiler" + echo " + using GNU C compiler" else if `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then NGX_CC_NAME=icc - echo " Intel C++ compiler" + echo " + using Intel C++ compiler" else if `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then NGX_CC_NAME=sunc - echo " Sun C compiler" + echo " + using Sun C compiler" else if `$CC -V 2>&1 | grep '^Compaq C' >/dev/null 2>&1`; then NGX_CC_NAME=ccc - echo " Compaq C compiler" + echo " + using Compaq C compiler" else if `$CC -V 2>&1 | grep '^aCC: ' >/dev/null 2>&1`; then NGX_CC_NAME=acc - echo " HP aC++ compiler" + echo " + using HP aC++ compiler" else NGX_CC_NAME=unknown - echo " unknown" fi # acc fi # ccc diff --git a/auto/feature b/auto/feature --- a/auto/feature +++ b/auto/feature @@ -41,7 +41,7 @@ ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLA ngx_feature_inc_path= -eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1" +eval "/bin/sh -c \"$ngx_test\" >> $NGX_AUTOCONF_ERR 2>&1" if [ -x $NGX_AUTOTEST ]; then diff --git a/auto/lib/perl/conf b/auto/lib/perl/conf --- a/auto/lib/perl/conf +++ b/auto/lib/perl/conf @@ -47,6 +47,7 @@ if test -n "$NGX_PERL_VER"; then if test -n "$NGX_PERL_MODULES"; then have=NGX_PERL_MODULES value="(u_char *) \"$NGX_PERL_MODULES\"" . auto/define + NGX_PERL_MODULES_MAN=$NGX_PERL_MODULES/man3 fi else diff --git a/auto/lib/perl/make b/auto/lib/perl/make --- a/auto/lib/perl/make +++ b/auto/lib/perl/make @@ -30,6 +30,7 @@ cat << END NGX_PCRE=$PCRE \ NGX_OBJS=$NGX_OBJS \ $NGX_PERL Makefile.PL \ - LIB=$NGX_PERL_MODULES + LIB=$NGX_PERL_MODULES \ + INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN END diff --git a/auto/os/conf b/auto/os/conf --- a/auto/os/conf +++ b/auto/os/conf @@ -42,6 +42,16 @@ case "$NGX_PLATFORM" in CORE_INCS="$UNIX_INCS" CORE_DEPS="$UNIX_DEPS $POSIX_DEPS" CORE_SRCS="$UNIX_SRCS" + + ngx_feature="atomic(3)" + ngx_feature_name=NGX_DARWIN_ATOMIC + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="int32_t lock, n; + n = OSAtomicCompareAndSwap32Barrier(0, 1, lock)" + . auto/feature ;; HP-UX:*) diff --git a/configure b/configure --- a/configure +++ b/configure @@ -3,6 +3,8 @@ # Copyright (C) Igor Sysoev +NGX_CONFIGURE=`echo $@ | sed 's/"/\\\\"/g'` + . auto/options . auto/init . auto/sources @@ -10,9 +12,10 @@ test -d $NGX_OBJS || mkdir $NGX_OBJS echo > $NGX_AUTO_HEADERS_H -echo > $NGX_AUTO_CONFIG_H echo > $NGX_AUTOCONF_ERR +echo "#define NGX_CONFIGURE \"$NGX_CONFIGURE\"" > $NGX_AUTO_CONFIG_H + if [ $NGX_DEBUG = YES ]; then have=NGX_DEBUG . auto/have @@ -32,14 +35,15 @@ if test -z "$NGX_PLATFORM"; then else echo "building for $NGX_PLATFORM" + NGX_SYSTEM=$NGX_PLATFORM fi +. auto/cc/conf if [ "$NGX_PLATFORM" != win32 ]; then . auto/headers fi -. auto/cc/conf . auto/os/conf if [ "$NGX_PLATFORM" != win32 ]; then diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -109,7 +109,7 @@ static ngx_command_t ngx_core_commands[ { ngx_string("worker_rlimit_core"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, + ngx_conf_set_size_slot, 0, offsetof(ngx_core_conf_t, rlimit_core), NULL }, @@ -176,6 +176,7 @@ ngx_module_t ngx_core_module = { ngx_uint_t ngx_max_module; static ngx_uint_t ngx_show_version; +static ngx_uint_t ngx_show_configure; static char *ngx_null_environ = NULL; @@ -235,10 +236,22 @@ main(int argc, char *const *argv) ngx_write_fd(ngx_stderr_fileno, "nginx version: " NGINX_VER CRLF, sizeof("nginx version: " NGINX_VER CRLF) - 1); + if (ngx_show_configure) { #ifdef NGX_COMPILER - ngx_write_fd(ngx_stderr_fileno, "built by " NGX_COMPILER CRLF, - sizeof("built by " NGX_COMPILER CRLF) - 1); + ngx_write_fd(ngx_stderr_fileno, "built by " NGX_COMPILER CRLF, + sizeof("built by " NGX_COMPILER CRLF) - 1); #endif + +#ifndef __WATCOMC__ + + /* OpenWatcomC could not build the long NGX_CONFIGURE string */ + + ngx_write_fd(ngx_stderr_fileno, + "configure arguments: " NGX_CONFIGURE CRLF, + sizeof("configure arguments :" NGX_CONFIGURE CRLF) - 1); +#endif + } + if (!ngx_test_config) { return 0; } @@ -252,6 +265,12 @@ main(int argc, char *const *argv) return 1; } + /* ngx_crc32_init() requires ngx_cacheline_size set in ngx_os_init() */ + + if (ngx_crc32_init() != NGX_OK) { + return 1; + } + if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) { return 1; } @@ -283,10 +302,6 @@ main(int argc, char *const *argv) ngx_os_status(cycle->log); - if (ngx_crc32_init(cycle->pool) != NGX_OK) { - return 1; - } - ngx_cycle = cycle; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); @@ -496,6 +511,11 @@ ngx_getopt(ngx_cycle_t *cycle, int argc, ngx_show_version = 1; break; + case 'V': + ngx_show_version = 1; + ngx_show_configure = 1; + break; + case 't': ngx_test_config = 1; break; @@ -600,7 +620,7 @@ ngx_core_module_create_conf(ngx_cycle_t ccf->debug_points = NGX_CONF_UNSET; ccf->rlimit_nofile = NGX_CONF_UNSET; - ccf->rlimit_core = NGX_CONF_UNSET; + ccf->rlimit_core = NGX_CONF_UNSET_SIZE; ccf->rlimit_sigpending = NGX_CONF_UNSET; ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT; 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_VERSION "0.5.4" +#define NGINX_VERSION "0.5.5" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_crc32.c b/src/core/ngx_crc32.c --- a/src/core/ngx_crc32.c +++ b/src/core/ngx_crc32.c @@ -102,7 +102,7 @@ uint32_t *ngx_crc32_table_short = ngx_cr ngx_int_t -ngx_crc32_init(ngx_pool_t *pool) +ngx_crc32_init(void) { void *p; @@ -113,7 +113,7 @@ ngx_crc32_init(ngx_pool_t *pool) return NGX_OK; } - p = ngx_palloc(pool, 16 * sizeof(uint32_t) + ngx_cacheline_size); + p = ngx_alloc(16 * sizeof(uint32_t) + ngx_cacheline_size, ngx_cycle->log); if (p == NULL) { return NGX_ERROR; } diff --git a/src/core/ngx_crc32.h b/src/core/ngx_crc32.h --- a/src/core/ngx_crc32.h +++ b/src/core/ngx_crc32.h @@ -49,7 +49,7 @@ ngx_crc32_long(u_char *p, size_t len) } -ngx_int_t ngx_crc32_init(ngx_pool_t *pool); +ngx_int_t ngx_crc32_init(void); #endif /* _NGX_CRC32_H_INCLUDED_ */ diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -759,7 +759,7 @@ ngx_create_pidfile(ngx_str_t *name, ngx_ size_t len; ngx_uint_t trunc; ngx_file_t file; - u_char pid[NGX_INT64_LEN]; + u_char pid[NGX_INT64_LEN + 2]; ngx_memzero(&file, sizeof(ngx_file_t)); @@ -778,7 +778,7 @@ ngx_create_pidfile(ngx_str_t *name, ngx_ } if (!ngx_test_config) { - len = ngx_sprintf(pid, "%P%N", ngx_pid) - pid; + len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid; if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) { return NGX_ERROR; diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -68,8 +68,8 @@ typedef struct { ngx_int_t debug_points; ngx_int_t rlimit_nofile; - ngx_int_t rlimit_core; ngx_int_t rlimit_sigpending; + size_t rlimit_core; int priority; 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 @@ -92,13 +92,14 @@ ngx_log_error_core(ngx_uint_t level, ngx p = errstr + ngx_cached_err_log_time.len; - p = ngx_sprintf(p, " [%s] ", err_levels[level]); + p = ngx_snprintf(p, last - p, " [%s] ", err_levels[level]); /* pid#tid */ - p = ngx_sprintf(p, "%P#" NGX_TID_T_FMT ": ", ngx_log_pid, ngx_log_tid); + p = ngx_snprintf(p, last - p, "%P#" NGX_TID_T_FMT ": ", + ngx_log_pid, ngx_log_tid); if (log->connection) { - p = ngx_sprintf(p, "*%uA ", log->connection); + p = ngx_snprintf(p, last - p, "*%uA ", log->connection); } #if (NGX_HAVE_VARIADIC_MACROS) diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c --- a/src/core/ngx_palloc.c +++ b/src/core/ngx_palloc.c @@ -85,14 +85,17 @@ void * ngx_palloc(ngx_pool_t *pool, size_t size) { u_char *m; - ngx_pool_t *p, *n; + ngx_pool_t *p, *n, *current; ngx_pool_large_t *large; if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL && size <= (size_t) (pool->end - (u_char *) pool) - (size_t) ngx_align_ptr(sizeof(ngx_pool_t), NGX_ALIGNMENT)) { - for (p = pool->current; /* void */ ; p = p->next) { + p = pool->current; + current = p; + + for ( ;; ) { if (size < sizeof(int) || (size & 1)) { m = p->last; @@ -108,12 +111,15 @@ ngx_palloc(ngx_pool_t *pool, size_t size } if ((size_t) (p->end - m) < NGX_ALIGNMENT) { - pool->current = p->next; + current = p->next; } if (p->next == NULL) { break; } + + p = p->next; + pool->current = current; } /* allocate a new pool block */ @@ -123,9 +129,7 @@ ngx_palloc(ngx_pool_t *pool, size_t size return NULL; } - if (pool->current == NULL) { - pool->current = n; - } + pool->current = current ? current : n; p->next = n; m = ngx_align_ptr(n->last, NGX_ALIGNMENT); diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -19,7 +19,7 @@ #define NGX_TIME_SLOTS 64 -static ngx_uint_t slot = NGX_TIME_SLOTS; +static ngx_uint_t slot; static ngx_atomic_t ngx_time_lock; volatile ngx_msec_t ngx_current_msec; diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c --- a/src/event/modules/ngx_eventport_module.c +++ b/src/event/modules/ngx_eventport_module.c @@ -468,7 +468,7 @@ ngx_eventport_process_events(ngx_cycle_t if (revents & (POLLERR|POLLHUP|POLLNVAL)) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "prot_getn() error fd:%d ev:%04Xd", + "port_getn() error fd:%d ev:%04Xd", event_list[i].portev_object, revents); } diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -847,7 +847,7 @@ ngx_http_proxy_process_status_line(ngx_h ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http proxy status %ui \"%V\"", - u->headers_in.status, &u->headers_in.status_line); + u->headers_in.status_n, &u->headers_in.status_line); u->process_header = ngx_http_proxy_process_header; diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.5.4'; +our $VERSION = '0.5.5'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -387,7 +387,10 @@ request_body(r) ngx_http_perl_set_request(r); - if (r->request_body->temp_file || r->request_body->bufs == NULL) { + if (r->request_body == NULL + || r->request_body->temp_file + || r->request_body->bufs == NULL) + { XSRETURN_UNDEF; } @@ -411,7 +414,7 @@ request_body_file(r) ngx_http_perl_set_request(r); - if (r->request_body->temp_file == NULL) { + if (r->request_body == NULL || r->request_body->temp_file == NULL) { XSRETURN_UNDEF; } 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 @@ -1104,7 +1104,9 @@ ngx_http_alloc_large_header_buffer(ngx_h if (r->host_start) { r->host_start = new + (r->host_start - old); - r->host_end = new + (r->host_end - old); + if (r->host_end) { + r->host_end = new + (r->host_end - old); + } } if (r->port_start) { diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -678,9 +678,13 @@ ngx_http_variable_host(ngx_http_request_ v->data = r->server_name.data; } - } else { + } else if (r->host_end) { v->len = r->host_end - r->host_start; v->data = r->host_start; + + } else { + v->not_found = 1; + return NGX_OK; } v->valid = 1; 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,6 +12,62 @@ #include +#if (NGX_DARWIN_ATOMIC) + +/* + * use Darwin 8 atomic(3) and barrier(3) operations + * optimized at run-time for UP and SMP + */ + +#include + +/* "bool" conflicts with perl's CORE/handy.h + * "true" and "false" conflict with nginx, and of course we can rename them, + * but we need to undef "bool" anyway + */ +#undef bool +#undef true +#undef false + + +#define NGX_HAVE_ATOMIC_OPS 1 + +#if (NGX_PTR_SIZE == 8) + +typedef int64_t ngx_atomic_int_t; +typedef uint64_t ngx_atomic_uint_t; +#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 + +#define ngx_atomic_cmp_set(lock, old, new) \ + OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock) + +#define ngx_atomic_fetch_add(value, add) \ + (OSAtomicAdd64(add, (int64_t *) value) - add) + +#else + +typedef int32_t ngx_atomic_int_t; +typedef uint32_t ngx_atomic_uint_t; +#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 + +#define ngx_atomic_cmp_set(lock, old, new) \ + OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock) + +#define ngx_atomic_fetch_add(value, add) \ + (OSAtomicAdd32(add, (int32_t *) value) - add) + +#endif + +#define ngx_memory_barrier() OSMemoryBarrier() + +#define ngx_cpu_pause() + +typedef volatile ngx_atomic_uint_t ngx_atomic_t; + + +#else /* !(NGX_DARWIN) */ + + #if ( __i386__ || __i386 ) typedef int32_t ngx_atomic_int_t; @@ -141,6 +197,8 @@ typedef volatile ngx_atomic_uint_t ngx_ #endif +#endif + #if !(NGX_HAVE_ATOMIC_OPS) @@ -181,6 +239,7 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #endif + void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin); #define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1)) diff --git a/src/os/unix/ngx_gcc_atomic_ppc.h b/src/os/unix/ngx_gcc_atomic_ppc.h --- a/src/os/unix/ngx_gcc_atomic_ppc.h +++ b/src/os/unix/ngx_gcc_atomic_ppc.h @@ -15,8 +15,15 @@ * any register except r0. The r0 register always has a zero value and * could not be used in "addi r0, r0, 1". * The "=&b" means that no input registers can be used. + * + * "sync" read and write barriers + * "isync" read barrier, is faster than "sync" + * "eieio" write barrier, is faster than "sync" + * "lwsync" write barrier, is faster than "eieio" on ppc64 */ +#if (NGX_PTR_SIZE == 8) + static ngx_inline ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, ngx_atomic_uint_t set) @@ -26,15 +33,18 @@ ngx_atomic_cmp_set(ngx_atomic_t *lock, n __asm__ volatile ( " li %0, 0 \n" /* preset "0" to "res" */ - " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ + " lwsync \n" /* write barrier */ + "1: \n" + " ldarx %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 */ + " cmpd %1, %3 \n" /* compare "temp" and "old" */ + " bne- 2f \n" /* not equal */ + " stdcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */ /* is not cleared */ - " bne- 1f \n" /* the reservation was cleared */ + " bne- 1b \n" /* the reservation was cleared */ + " isync \n" /* read barrier */ " li %0, 1 \n" /* set "1" to "res" */ - "1: \n" + "2: \n" : "=&b" (res), "=&b" (temp) : "b" (lock), "b" (old), "b" (set) @@ -51,12 +61,14 @@ ngx_atomic_fetch_add(ngx_atomic_t *value __asm__ volatile ( - "1: lwarx %0, 0, %2 \n" /* load from [value] into "res" */ + " lwsync \n" /* write barrier */ + "1: ldarx %0, 0, %2 \n" /* load from [value] into "res" */ /* and store reservation */ " add %1, %0, %3 \n" /* "res" + "add" store in "temp" */ - " stwcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */ + " stdcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */ /* is not cleared */ " bne- 1b \n" /* try again if reservation was cleared */ + " isync \n" /* read barrier */ : "=&b" (res), "=&b" (temp) : "b" (value), "b" (add) @@ -67,9 +79,76 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #if (NGX_SMP) -#define ngx_memory_barrier() __asm__ volatile ("sync\n" ::: "memory") +#define ngx_memory_barrier() \ + __asm__ volatile ("isync \n lwsync \n" ::: "memory") #else #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory") #endif +#else + +static ngx_inline ngx_atomic_uint_t +ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, + ngx_atomic_uint_t set) +{ + ngx_atomic_uint_t res, temp; + + __asm__ volatile ( + + " li %0, 0 \n" /* preset "0" to "res" */ + " eieio \n" /* write barrier */ + "1: \n" + " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ + /* and store reservation */ + " cmpw %1, %3 \n" /* compare "temp" and "old" */ + " bne- 2f \n" /* not equal */ + " stwcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */ + /* is not cleared */ + " bne- 1b \n" /* the reservation was cleared */ + " isync \n" /* read barrier */ + " li %0, 1 \n" /* set "1" to "res" */ + "2: \n" + + : "=&b" (res), "=&b" (temp) + : "b" (lock), "b" (old), "b" (set) + : "cc", "memory"); + + return res; +} + + +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + ngx_atomic_uint_t res, temp; + + __asm__ volatile ( + + " eieio \n" /* write barrier */ + "1: lwarx %0, 0, %2 \n" /* load from [value] into "res" */ + /* and store reservation */ + " add %1, %0, %3 \n" /* "res" + "add" store in "temp" */ + " stwcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */ + /* is not cleared */ + " bne- 1b \n" /* try again if reservation was cleared */ + " isync \n" /* read barrier */ + + : "=&b" (res), "=&b" (temp) + : "b" (value), "b" (add) + : "cc", "memory"); + + return res; +} + + +#if (NGX_SMP) +#define ngx_memory_barrier() \ + __asm__ volatile ("isync \n eieio \n" ::: "memory") +#else +#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory") +#endif + +#endif + + #define ngx_cpu_pause() diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -444,10 +444,14 @@ ngx_process_get_status(void) return; } -#if (NGX_SOLARIS) +#if (NGX_SOLARIS || NGX_FREEBSD) /* * Solaris always calls the signal handler for each exited process + * despite waitpid() may be already called for this process. + * + * When several processes exit at the same time FreeBSD may + * erroneously call the signal handler for exited process * despite waitpid() may be already called for this process */ diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -787,7 +787,7 @@ ngx_worker_process_init(ngx_cycle_t *cyc } } - if (ccf->rlimit_core != NGX_CONF_UNSET) { + if (ccf->rlimit_core != NGX_CONF_UNSET_SIZE) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_core; rlmt.rlim_max = (rlim_t) ccf->rlimit_core;