nginx-0.0.2-2004-03-01-00:03:02 import
diff --git a/src/core/ngx_atomic.h b/src/core/ngx_atomic.h index 5f5add9..bf771e9 100644 --- a/src/core/ngx_atomic.h +++ b/src/core/ngx_atomic.h
@@ -59,7 +59,7 @@ 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 index bfdd98b..c49e198 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c
@@ -22,6 +22,9 @@ 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 @@ 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 @@ 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 @@ /* TODO: non-thread mode only */ - ev = ngx_posted_events; - ngx_posted_events = NULL; + for ( ;; ) { - while (ev) { + ev = (ngx_event_t *) ngx_posted_events; + + 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 index 820a5f5..cfd40d7 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c
@@ -39,13 +39,13 @@ 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 index 899db18..17462df 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h
@@ -20,6 +20,14 @@ #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 @@ -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 index 5a9542b..9f1868f 100644 --- 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 <ngx_config.h> +#include <ngx_core.h> +#include <ngx_event.h> -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); - return 0; + 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 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 index 498fd9f..8983d99 100644 --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c
@@ -9,22 +9,26 @@ #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 @@ } #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 @@ } #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 index 300d79c..568a97c 100644 --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h
@@ -31,8 +31,8 @@ #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 @@ } #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 @@ } #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 index 30cec23..e4f682f 100644 --- a/src/http/ngx_http_busy_lock.c +++ b/src/http/ngx_http_busy_lock.c
@@ -40,6 +40,7 @@ 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 @@ } *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 index e600b01..dd7ab6f 100644 --- 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 index dd18168..e100b93 100644 --- a/src/os/unix/ngx_freebsd_rfork_thread.c +++ b/src/os/unix/ngx_freebsd_rfork_thread.c
@@ -1,4 +1,9 @@ +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + + #include <ngx_config.h> #include <ngx_core.h> @@ -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 @@ /* - * __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 @@ ngx_int_t tries; tries = 0; + for ( ;; ) { if (*lock) { @@ -88,6 +91,24 @@ } +/* + * 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ } -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 @@ } -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 @@ 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 index 24753c4..2fcd6f3 100644 --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -1,4 +1,9 @@ +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + + #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h>
diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c index 4fa8f83..463fdda 100644 --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c
@@ -1,4 +1,9 @@ +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + + #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h>
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c index a8c9610..3210819 100644 --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c
@@ -13,9 +13,12 @@ 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 @@ return NGX_ERROR; } } +#endif pid = fork(); @@ -34,11 +38,13 @@ } 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_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 index 9cd1618..f428261 100644 --- a/src/os/unix/ngx_solaris_sendfilev_chain.c +++ b/src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -1,4 +1,9 @@ +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + + #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h>
diff --git a/src/os/unix/ngx_thread.h b/src/os/unix/ngx_thread.h index 3961f32..8a02880 100644 --- 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 - -#define ngx_log_tid 0 - #undef ngx_log_pid #define ngx_log_pid ngx_thread_self() +#define ngx_log_tid 0 + +#define TID_T_FMT PID_T_FMT #define NGX_MUTEX_LIGHT 1 @@ -35,12 +34,43 @@ } 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 <pthread.h> 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 @@ 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);