# HG changeset patch # User Igor Sysoev # Date 1078088582 0 # Node ID d4e65d74db9f18e6d2cc55c19b724335b1d26bae # Parent e16dfb9b9afa3bcdaf96236cf1baaca2fb11e3ac nginx-0.0.2-2004-03-01-00:03:02 import diff --git a/auto/cc b/auto/cc --- a/auto/cc +++ b/auto/cc @@ -5,6 +5,10 @@ case $CC in # optimization #CFLAGS="$CFLAGS -O2 -fomit-frame-pointer" + # optimize for Pentium Pro, Pentium II and Pentium III + CFLAGS="$CFLAGS -mcpu=pentiumpro" + # optimize for Pentium 4, gcc 3.x + #CFLAGS="$CFLAGS -mcpu=pentium4" # warnings CFLAGS="$CFLAGS -O -W" @@ -40,7 +44,7 @@ case $CC in # optimization CFLAGS="$CFLAGS -O" # optimize for Pentium Pro, Pentium II and Pentium III - #CFLAGS="$CFLAGS -mcpu=pentiumpro" + CFLAGS="$CFLAGS -mcpu=pentiumpro" # optimize for Pentium 4, default #CFLAGS="$CFLAGS -mcpu=pentium4" diff --git a/auto/lib/make b/auto/lib/make --- a/auto/lib/make +++ b/auto/lib/make @@ -11,29 +11,7 @@ if [ "$PLATFORM" != "win32" ]; then if [ $MD5 != NO ]; then - echo "$MD5/libmd5.a:" >> $MAKEFILE - - case $PLATFORM in - - SunOS:*:i386) - echo " cd $MD5 && \$(MAKE) x86-solaris" >> $MAKEFILE - ;; - - *:i386) - echo " cd $MD5 && \$(MAKE) x86-elf" >> $MAKEFILE - ;; - - *) - if [ $CC = gcc ]; then - echo " cd $MD5 && \$(MAKE) gcc" >> $MAKEFILE - else - echo " cd $MD5 && \$(MAKE) cc" >> $MAKEFILE - fi - ;; - - esac - - echo >> $MAKEFILE + . auto/lib/md5/make fi diff --git a/auto/os/freebsd b/auto/os/freebsd --- a/auto/os/freebsd +++ b/auto/os/freebsd @@ -24,7 +24,7 @@ fi # sendfile if [ $version -gt 300007 ]; then - echo " + sendfile() found" + echo " + using sendfile()" have=HAVE_SENDFILE . auto/have CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS" @@ -36,7 +36,7 @@ fi if [ \( $version -lt 500000 -a $version -ge 410000 \) \ -o $version -ge 500011 ] then - echo " + kqueue found" + echo " + using kqueue" have=HAVE_KQUEUE . auto/have have=HAVE_CLEAR_EVENT . auto/have @@ -51,7 +51,7 @@ fi if [ \( $version -lt 500000 -a $version -ge 430000 \) \ -o $version -ge 500018 ] then - echo " + kqueue's NOTE_LAWAT found" + echo " + using kqueue's NOTE_LAWAT" have=HAVE_LOWAT_EVENT . auto/have fi diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -57,6 +57,7 @@ EVENT_DEPS="src/event/ngx_event.h \ EVENT_SRCS="src/event/ngx_event.c \ src/event/ngx_event_timer.c \ + src/event/ngx_event_mutex.c \ src/event/ngx_event_accept.c \ src/event/ngx_event_connect.c \ src/event/ngx_event_pipe.c" diff --git a/src/core/ngx_atomic.h b/src/core/ngx_atomic.h --- a/src/core/ngx_atomic.h +++ b/src/core/ngx_atomic.h @@ -59,7 +59,7 @@ static ngx_inline uint32_t ngx_atomic_cm NGX_SMP_LOCK " cmpxchgl %3, %1; " - " setzb %%al; " + " setz %%al; " " movzbl %%al, %0; " : "=a" (res) : "m" (*lock), "a" (old), "q" (set)); diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -22,6 +22,9 @@ static int ngx_kqueue_add_event(ngx_even static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags); static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags); static int ngx_kqueue_process_events(ngx_log_t *log); +#if (NGX_THREADS) +static void ngx_kqueue_thread_handler(ngx_event_t *ev); +#endif static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle); static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf); @@ -68,6 +71,9 @@ ngx_event_module_t ngx_kqueue_module_ct NULL, /* add an connection */ NULL, /* delete an connection */ ngx_kqueue_process_events, /* process the events */ +#if (NGX_THREADS0) + ngx_kqueue_thread_handler, /* process an event by thread */ +#endif ngx_kqueue_init, /* init the events */ ngx_kqueue_done /* done the events */ } @@ -500,7 +506,12 @@ static ngx_int_t ngx_kqueue_process_even if (ev->light) { - /* the accept event */ + /* + * The light events are the accept event, + * or the event that waits in the mutex queue - we need to + * remove it from the mutex queue before the inserting into + * the posted events queue. + */ ngx_mutex_unlock(ngx_posted_events_mutex); @@ -538,12 +549,17 @@ static ngx_int_t ngx_kqueue_process_even /* TODO: non-thread mode only */ - ev = ngx_posted_events; - ngx_posted_events = NULL; + for ( ;; ) { + + ev = (ngx_event_t *) ngx_posted_events; - while (ev) { + if (ev == NULL) { + break; + } + + ngx_posted_events = ev->next; + ev->event_handler(ev); - ev = ev->next; } return NGX_OK; 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 @@ -39,13 +39,13 @@ static void *ngx_event_create_conf(ngx_c static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf); -int ngx_event_flags; -ngx_event_actions_t ngx_event_actions; +int ngx_event_flags; +ngx_event_actions_t ngx_event_actions; -static int ngx_event_max_module; +static int ngx_event_max_module; -ngx_event_t *ngx_posted_events; +volatile ngx_event_t *ngx_posted_events; static ngx_str_t events_name = ngx_string("events"); diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -20,6 +20,14 @@ typedef struct { #endif +typedef struct { + ngx_uint_t lock; + + ngx_event_t *events; + ngx_event_t *last; +} ngx_event_mutex_t; + + struct ngx_event_s { void *data; /* TODO rename to handler */ @@ -373,11 +381,11 @@ typedef struct { -extern ngx_event_t *ngx_posted_events; +extern volatile ngx_event_t *ngx_posted_events; -extern int ngx_event_flags; -extern ngx_module_t ngx_events_module; -extern ngx_module_t ngx_event_core_module; +extern int ngx_event_flags; +extern ngx_module_t ngx_events_module; +extern ngx_module_t ngx_event_core_module; #define ngx_event_get_conf(conf_ctx, module) \ diff --git a/src/event/ngx_event_mutex.c b/src/event/ngx_event_mutex.c --- a/src/event/ngx_event_mutex.c +++ b/src/event/ngx_event_mutex.c @@ -1,14 +1,65 @@ -spinlock_max depend on CPU number and mutex type. - 1 CPU 1 - ngx_malloc_mutex 1000 ? +#include +#include +#include -int ngx_event_mutex_trylock(ngx_mutex_t *mtx) +ngx_int_t ngx_event_mutex_timedlock(ngx_event_mutex_t *m, ngx_msec_t timer, + ngx_event_t *ev) { - for(i = mtx->spinlock_max; i; i--) - if (trylock(mtx->lock)) - return 1; + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "lock event mutex " PTR_FMT " lock:%X", m, m->lock); + + if (m->lock) { + + if (m->events == NULL) { + m->events = ev; + + } else { + m->last->next = ev; + } + + m->last = ev; + ev->next = NULL; + +#if (NGX_THREADS) + ev->light = 1; +#endif + + ngx_add_timer(ev, timer); + + return NGX_AGAIN; + } + + m->lock = 1; - return 0; + return NGX_OK; } + + +ngx_int_t ngx_event_mutex_unlock(ngx_event_mutex_t *m, ngx_log_t *log) +{ + ngx_event_t *ev; + + if (m->lock == 0) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "tring to unlock the free event mutex " PTR_FMT, m); + return NGX_ERROR; + } + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "unlock event mutex " PTR_FMT ", next event: " PTR_FMT, + m, m->events); + + m->lock = 0; + + if (m->events) { + ev = m->events; + m->events = ev->next; + + ev->next = (ngx_event_t *) ngx_posted_events; + ngx_posted_events = ev; + } + + return NGX_OK; +} 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 @@ -9,22 +9,26 @@ ngx_mutex_t *ngx_event_timer_mutex; #endif -ngx_rbtree_t *ngx_event_timer_rbtree; -ngx_rbtree_t ngx_event_timer_sentinel; +volatile ngx_rbtree_t *ngx_event_timer_rbtree; +ngx_rbtree_t ngx_event_timer_sentinel; ngx_int_t ngx_event_timer_init(ngx_log_t *log) { if (ngx_event_timer_rbtree) { +#if (NGX_THREADS) ngx_event_timer_mutex->log = log; +#endif return NGX_OK; } ngx_event_timer_rbtree = &ngx_event_timer_sentinel; +#if (NGX_THREADS) if (!(ngx_event_timer_mutex = ngx_mutex_init(log, 0))) { return NGX_ERROR; } +#endif return NGX_OK; } @@ -44,7 +48,8 @@ ngx_msec_t ngx_event_find_timer(void) } #endif - node = ngx_rbtree_min(ngx_event_timer_rbtree, &ngx_event_timer_sentinel); + node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree, + &ngx_event_timer_sentinel); #if (NGX_THREADS) ngx_mutex_unlock(ngx_event_timer_mutex); @@ -76,7 +81,7 @@ void ngx_event_expire_timers(ngx_msec_t } #endif - node = ngx_rbtree_min(ngx_event_timer_rbtree, + node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree, &ngx_event_timer_sentinel); #if (NGX_THREADS) 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 @@ -31,8 +31,8 @@ extern ngx_mutex_t *ngx_event_timer_mut #endif -extern ngx_rbtree_t *ngx_event_timer_rbtree; -extern ngx_rbtree_t ngx_event_timer_sentinel; +extern volatile ngx_rbtree_t *ngx_event_timer_rbtree; +extern ngx_rbtree_t ngx_event_timer_sentinel; ngx_inline static void ngx_event_del_timer(ngx_event_t *ev) @@ -47,7 +47,8 @@ ngx_inline static void ngx_event_del_tim } #endif - ngx_rbtree_delete(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel, + ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree, + &ngx_event_timer_sentinel, (ngx_rbtree_t *) &ev->rbtree_key); #if (NGX_THREADS) @@ -87,7 +88,8 @@ ngx_inline static void ngx_event_add_tim } #endif - ngx_rbtree_insert(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel, + ngx_rbtree_insert((ngx_rbtree_t **) &ngx_event_timer_rbtree, + &ngx_event_timer_sentinel, (ngx_rbtree_t *) &ev->rbtree_key); #if (NGX_THREADS) diff --git a/src/http/ngx_http_busy_lock.c b/src/http/ngx_http_busy_lock.c --- a/src/http/ngx_http_busy_lock.c +++ b/src/http/ngx_http_busy_lock.c @@ -40,6 +40,7 @@ int ngx_http_busy_lock(ngx_http_busy_loc if (bl->waiting < bl->max_waiting) { bl->waiting++; + ngx_add_timer(bc->event, 1000); bc->event->event_handler = bc->event_handler; @@ -204,6 +205,11 @@ char *ngx_http_set_busy_lock_slot(ngx_co } *blp = bl; + /* ngx_calloc_shared() */ + if (!(bl->mutex = ngx_pcalloc(cf->pool, sizeof(ngx_event_mutex_t)))) { + return NGX_CONF_ERROR; + } + dup = 0; invalid = 0; value = cf->args->elts; diff --git a/src/http/ngx_http_busy_lock.h b/src/http/ngx_http_busy_lock.h --- a/src/http/ngx_http_busy_lock.h +++ b/src/http/ngx_http_busy_lock.h @@ -9,20 +9,19 @@ typedef struct { - u_char *md5_mask; - char *md5; - int cachable; + u_char *md5_mask; + char *md5; + int cachable; - int busy; - int max_busy; + int busy; + int max_busy; - int waiting; - int max_waiting; + int waiting; + int max_waiting; - time_t timeout; + time_t timeout; - /* ngx_mutex_t mutex; */ - + ngx_event_mutex_t *mutex; } ngx_http_busy_lock_t; diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c --- a/src/os/unix/ngx_freebsd_rfork_thread.c +++ b/src/os/unix/ngx_freebsd_rfork_thread.c @@ -1,3 +1,8 @@ + +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + #include #include @@ -21,15 +26,12 @@ */ -ngx_int_t ngx_threaded; - -static inline int ngx_gettid(); +ngx_int_t ngx_threaded; +char *ngx_freebsd_kern_usrstack; +size_t ngx_thread_stack_size; -static char *usrstack; static size_t rz_size = /* STUB: PAGE_SIZE */ 4096; - -static size_t stack_size; static size_t usable_stack_size; static char *last_stack; @@ -54,12 +56,12 @@ int *__error() /* - * __isthreaded enables spinlock() in some libc functions, i.e. in malloc() + * __isthreaded enables the spinlocks in some libc functions, i.e. in malloc() * and some other places. Nevertheless we protect our malloc()/free() calls * by own mutex that is more efficient than the spinlock. * - * We define own _spinlock() because a weak referenced _spinlock() stub in - * src/lib/libc/gen/_spinlock_stub.c does nothing. + * _spinlock() is a weak referenced stub in src/lib/libc/gen/_spinlock_stub.c + * that does nothing. */ extern int __isthreaded; @@ -69,6 +71,7 @@ void _spinlock(ngx_atomic_t *lock) ngx_int_t tries; tries = 0; + for ( ;; ) { if (*lock) { @@ -88,6 +91,24 @@ void _spinlock(ngx_atomic_t *lock) } +/* + * Before FreeBSD 5.1 _spinunlock() is a simple #define in + * src/lib/libc/include/spinlock.h that zeroes lock. + * + * Since FreeBSD 5.1 _spinunlock() is a weak referenced stub in + * src/lib/libc/gen/_spinlock_stub.c that does nothing. + */ + +#ifndef _spinunlock + +void _spinunlock(ngx_atomic_t *lock) +{ + *lock = 0; +} + +#endif + + int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg, ngx_log_t *log) { @@ -100,7 +121,7 @@ int ngx_create_thread(ngx_tid_t *tid, in return NGX_ERROR; } - last_stack -= stack_size; + last_stack -= ngx_thread_stack_size; stack = mmap(last_stack, usable_stack_size, PROT_READ|PROT_WRITE, MAP_STACK, -1, 0); @@ -139,7 +160,8 @@ int ngx_create_thread(ngx_tid_t *tid, in } else { *tid = id; - nthreads = (usrstack - stack_top) / stack_size; + nthreads = (ngx_freebsd_kern_usrstack - stack_top) + / ngx_thread_stack_size; tids[nthreads] = id; ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "rfork()ed thread: %d", id); @@ -156,19 +178,21 @@ ngx_int_t ngx_init_threads(int n, size_t max_threads = n; - len = sizeof(usrstack); - if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) { + len = sizeof(ngx_freebsd_kern_usrstack); + if (sysctlbyname("kern.usrstack", &ngx_freebsd_kern_usrstack, &len, + NULL, 0) == -1) + { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sysctlbyname(kern.usrstack) failed"); return NGX_ERROR; } /* the main thread stack red zone */ - red_zone = usrstack - (size + rz_size); + red_zone = ngx_freebsd_kern_usrstack - (size + rz_size); ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, "usrstack: " PTR_FMT " red zone: " PTR_FMT, - usrstack, red_zone); + ngx_freebsd_kern_usrstack, red_zone); zone = mmap(red_zone, rz_size, PROT_NONE, MAP_ANON, -1, 0); if (zone == MAP_FAILED) { @@ -201,7 +225,7 @@ ngx_int_t ngx_init_threads(int n, size_t last_stack = zone + rz_size; usable_stack_size = size; - stack_size = size + rz_size; + ngx_thread_stack_size = size + rz_size; /* allow the spinlock in libc malloc() */ __isthreaded = 1; @@ -212,28 +236,6 @@ ngx_int_t ngx_init_threads(int n, size_t } -static inline int ngx_gettid() -{ - char *sp; - - if (stack_size == 0) { - return 0; - } - -#if ( __i386__ ) - - __asm__ volatile ("mov %%esp, %0" : "=q" (sp)); - -#elif ( __amd64__ ) - - __asm__ volatile ("mov %%rsp, %0" : "=q" (sp)); - -#endif - - return (usrstack - sp) / stack_size; -} - - ngx_tid_t ngx_thread_self() { int tid; @@ -313,7 +315,7 @@ void ngx_mutex_done(ngx_mutex_t *m) } -ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try) +ngx_int_t ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try) { uint32_t lock, new, old; ngx_uint_t tries; @@ -453,7 +455,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t * old = m->lock; if (!(old & NGX_MUTEX_LOCK_BUSY)) { - ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno, + ngx_log_error(NGX_LOG_ALERT, m->log, 0, "tring to unlock the free mutex " PTR_FMT, m); return NGX_ERROR; } diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -1,3 +1,8 @@ + +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + #include #include diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -1,3 +1,8 @@ + +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + #include #include 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 @@ -13,9 +13,12 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn) { +#if 0 sigset_t set, oset; +#endif ngx_pid_t pid; +#if 0 if (respawn < 0) { sigemptyset(&set); sigaddset(&set, SIGCHLD); @@ -25,6 +28,7 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t return NGX_ERROR; } } +#endif pid = fork(); @@ -34,11 +38,13 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t } if (pid == -1 || pid == 0) { +#if 0 if (sigprocmask(SIG_SETMASK, &oset, &set) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed while spawning %s", name); return NGX_ERROR; } +#endif } switch (pid) { @@ -75,11 +81,13 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t ngx_processes[ngx_last_process].exiting = 0; ngx_last_process++; +#if 0 if (sigprocmask(SIG_SETMASK, &oset, &set) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed while spawning %s", name); return NGX_ERROR; } +#endif return pid; } diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c --- a/src/os/unix/ngx_solaris_sendfilev_chain.c +++ b/src/os/unix/ngx_solaris_sendfilev_chain.c @@ -1,3 +1,8 @@ + +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + #include #include diff --git a/src/os/unix/ngx_thread.h b/src/os/unix/ngx_thread.h --- a/src/os/unix/ngx_thread.h +++ b/src/os/unix/ngx_thread.h @@ -15,12 +15,11 @@ typedef pid_t ngx_tid_t; -#define TID_T_FMT PID_T_FMT - +#undef ngx_log_pid +#define ngx_log_pid ngx_thread_self() #define ngx_log_tid 0 -#undef ngx_log_pid -#define ngx_log_pid ngx_thread_self() +#define TID_T_FMT PID_T_FMT #define NGX_MUTEX_LIGHT 1 @@ -35,12 +34,43 @@ typedef volatile struct { } ngx_mutex_t; +extern char *ngx_freebsd_kern_usrstack; +extern size_t ngx_thread_stack_size; + +static inline int ngx_gettid() +{ + char *sp; + + if (ngx_thread_stack_size == 0) { + return 0; + } + +#if ( __i386__ ) + + __asm__ volatile ("mov %%esp, %0" : "=q" (sp)); + +#elif ( __amd64__ ) + + __asm__ volatile ("mov %%rsp, %0" : "=q" (sp)); + +#else + +#error "rfork()ed threads are not supported on this platform" + +#endif + + return (ngx_freebsd_kern_usrstack - sp) / ngx_thread_stack_size; +} + + + #else /* use pthreads */ #include typedef pthread_t ngx_tid_t; +#define ngx_gettid() ((ngx_int_t) pthread_getspecific(0)) #define ngx_log_tid ngx_thread_self() #endif @@ -51,12 +81,13 @@ int ngx_create_thread(ngx_tid_t *tid, in ngx_log_t *log); ngx_tid_t ngx_thread_self(); + ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, uint flags); void ngx_mutex_done(ngx_mutex_t *m); -#define ngx_mutex_trylock(m) ngx_mutex_do_lock(m, 1) -#define ngx_mutex_lock(m) ngx_mutex_do_lock(m, 0) -ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try); +#define ngx_mutex_trylock(m) ngx_mutex_dolock(m, 1) +#define ngx_mutex_lock(m) ngx_mutex_dolock(m, 0) +ngx_int_t ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try); ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m);