# HG changeset patch # User Igor Sysoev # Date 1081974845 0 # Node ID a0beefedaf94d94271bc443d03e85c63e6f7e58d # Parent 39b6f2df45c0521b119bbd6e3b085f7681e66717 nginx-0.0.3-2004-04-15-00:34:05 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -277,6 +277,13 @@ static ngx_int_t ngx_getopt(ngx_master_c switch (ctx->argv[i][1]) { case 'c': + if (ctx->argv[i + 1] == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "the option: \"%s\" requires file name", + ctx->argv[i]); + return NGX_ERROR; + } + cycle->conf_file.data = (u_char *) ctx->argv[++i]; cycle->conf_file.len = ngx_strlen(cycle->conf_file.data); break; diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -101,11 +101,6 @@ typedef int ngx_flag_t; #define ngx_inline inline #endif - -#ifndef INFTIM /* Linux */ -#define INFTIM -1 -#endif - #ifndef INADDR_NONE /* Solaris */ #define INADDR_NONE ((unsigned int) -1) #endif 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 @@ -23,7 +23,7 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t { void *rv; ngx_uint_t i, n, failed; - ngx_log_t *log; + ngx_log_t *log, *new_log; ngx_conf_t conf; ngx_pool_t *pool; ngx_cycle_t *cycle, **old; @@ -44,6 +44,9 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t } cycle->pool = pool; + pool->log = log; + cycle->log = log; + cycle->old_cycle = old_cycle; cycle->conf_file = old_cycle->conf_file; @@ -71,7 +74,7 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t cycle->open_files.pool = pool; - if (!(cycle->log = ngx_log_create_errlog(cycle, NULL))) { + if (!(new_log = ngx_log_create_errlog(cycle, NULL))) { ngx_destroy_pool(pool); return NULL; } @@ -129,12 +132,14 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t conf.module_type = NGX_CORE_MODULE; conf.cmd_type = NGX_MAIN_CONF; + cycle->log = new_log; if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) { ngx_destroy_pool(pool); return NULL; } + cycle->log = log; for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_CORE_MODULE) { @@ -203,6 +208,8 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t } } + cycle->log = new_log; + pool->log = new_log; if (!failed) { if (old_cycle->listening.nelts) { diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -236,6 +236,7 @@ static int ngx_devpoll_del_event(ngx_eve } ev->active = 0; + ev->posted = 0; if (flags & NGX_CLOSE_EVENT) { return NGX_OK; @@ -312,7 +313,7 @@ int ngx_devpoll_process_events(ngx_cycle { int events; ngx_int_t i; - ngx_uint_t j; + ngx_uint_t j, lock, expire; size_t n; ngx_msec_t timer; ngx_err_t err; @@ -322,13 +323,43 @@ int ngx_devpoll_process_events(ngx_cycle struct dvpoll dvp; struct timeval tv; - timer = ngx_event_find_timer(); - ngx_old_elapsed_msec = ngx_elapsed_msec; + for ( ;; ) { + timer = ngx_event_find_timer(); + + if (timer != 0) { + break; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "devpoll expired timer"); + + ngx_event_expire_timers(0); + } + + /* NGX_TIMER_INFINITE == INFTIM */ + + if (timer == NGX_TIMER_INFINITE) { + expire = 0; - if (timer == 0) { - timer = (ngx_msec_t) INFTIM; + } else { + expire = 1; } + if (ngx_accept_mutex) { + if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { + return NGX_ERROR; + } + + if (ngx_accept_mutex_held == 0 + && (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay)) + { + timer = ngx_accept_mutex_delay; + expire = 0; + } + } + + ngx_old_elapsed_msec = ngx_elapsed_msec; + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "devpoll timer: %d", timer); @@ -337,6 +368,7 @@ int ngx_devpoll_process_events(ngx_cycle if (write(dp, change_list, n) != (ssize_t) n) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "write(/dev/poll) failed"); + ngx_accept_mutex_unlock(); return NGX_ERROR; } } @@ -363,10 +395,11 @@ int ngx_devpoll_process_events(ngx_cycle if (err) { ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, cycle->log, err, "ioctl(DP_POLL) failed"); + ngx_accept_mutex_unlock(); return NGX_ERROR; } - if (timer != (ngx_msec_t) INFTIM) { + if (timer != NGX_TIMER_INFINITE) { delta = ngx_elapsed_msec - delta; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, @@ -375,10 +408,18 @@ int ngx_devpoll_process_events(ngx_cycle if (events == 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "ioctl(DP_POLL) returned no events without timeout"); + ngx_accept_mutex_unlock(); return NGX_ERROR; } } + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + ngx_accept_mutex_unlock(); + return NGX_ERROR; + } + + lock = 1; + for (i = 0; i < events; i++) { c = &ngx_cycle->connections[event_list[i].fd]; @@ -421,25 +462,68 @@ int ngx_devpoll_process_events(ngx_cycle event_list[i].events, event_list[i].revents); } + if ((event_list[i].events & (POLLOUT|POLLERR|POLLHUP)) + && c->write->active) + { + c->write->ready = 1; + + if (!ngx_threaded && !ngx_accept_mutex_held) { + c->write->event_handler(c->write); + + } else { + ngx_post_event(c->write); + } + } + + /* + * POLLIN must be handled after POLLOUT because we use + * the optimization to avoid the unnecessary mutex locking/unlocking + * if the accept event is the last one. + */ + if ((event_list[i].events & (POLLIN|POLLERR|POLLHUP)) && c->read->active) { c->read->ready = 1; - c->read->event_handler(c->read); - } + + if (!ngx_threaded && !ngx_accept_mutex_held) { + c->read->event_handler(c->read); + + } else if (!c->read->accept) { + ngx_post_event(c->read); + + } else { + ngx_mutex_unlock(ngx_posted_events_mutex); - if ((event_list[i].events & (POLLOUT|POLLERR|POLLHUP)) - && c->write->active) - { - c->write->ready = 1; - c->write->event_handler(c->write); + c->read->event_handler(c->read); + + if (i + 1 == events) { + lock = 0; + break; + } + + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + ngx_accept_mutex_unlock(); + return NGX_ERROR; + } + } } } - if (timer != (ngx_msec_t) INFTIM && delta) { + if (lock) { + ngx_mutex_unlock(ngx_posted_events_mutex); + } + + ngx_accept_mutex_unlock(); + + if (expire && delta) { ngx_event_expire_timers((ngx_msec_t) delta); } + if (!ngx_threaded) { + ngx_event_process_posted(cycle); + } + return NGX_OK; } diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -353,28 +353,37 @@ int ngx_epoll_process_events(ngx_cycle_t ngx_connection_t *c; ngx_epoch_msec_t delta; - timer = ngx_event_find_timer(); - ngx_old_elapsed_msec = ngx_elapsed_msec; + for ( ;; ) { + timer = ngx_event_find_timer(); + + if (timer != 0) { + break; + } - if (timer == -1) { - timer = 0; - expire = 1; + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "epoll expired timer"); - } else if (timer == 0) { - timer = (ngx_msec_t) -1; + ngx_event_expire_timers(0); + } + + /* NGX_TIMER_INFINITE == INFTIM */ + + if (timer == NGX_TIMER_INFINITE) { expire = 0; } else { expire = 1; } + ngx_old_elapsed_msec = ngx_elapsed_msec; + if (ngx_accept_mutex) { if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { return NGX_ERROR; } if (ngx_accept_mutex_held == 0 - && (timer == -1 || timer > ngx_accept_mutex_delay)) + && (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay)) { timer = ngx_accept_mutex_delay; expire = 0; @@ -398,7 +407,7 @@ int ngx_epoll_process_events(ngx_cycle_t delta = ngx_elapsed_msec; ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; - if (timer != (ngx_msec_t) -1) { + if (timer != NGX_TIMER_INFINITE) { delta = ngx_elapsed_msec - delta; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 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 @@ -353,20 +353,34 @@ static ngx_int_t ngx_kqueue_process_even struct timeval tv; struct timespec ts, *tp; - timer = ngx_event_find_timer(); + for ( ;; ) { + timer = ngx_event_find_timer(); #if (NGX_THREADS) - if (timer == NGX_TIMER_ERROR) { - return NGX_ERROR; - } + if (timer == NGX_TIMER_ERROR) { + return NGX_ERROR; + } - /* - * TODO: if timer is 0 and any worker thread is still busy - * then set 500 ms timeout - */ + /* + * TODO: if timer is NGX_TIMER_INFINITE and any worker thread + * is still busy then set the configurable 500ms timeout + * to wake up another worker thread + */ #endif + if (timer != 0) { + break; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "kevent expired timer"); + + ngx_event_expire_timers(0); + + /* TODO: if ngx_threaded then wake up the worker thread */ + } + ngx_old_elapsed_msec = ngx_elapsed_msec; expire = 1; @@ -376,26 +390,21 @@ static ngx_int_t ngx_kqueue_process_even } if (ngx_accept_mutex_held == 0 - && (timer == 0 || timer > ngx_accept_mutex_delay)) + && (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay)) { timer = ngx_accept_mutex_delay; expire = 0; } } - if (timer == -1) { - ts.tv_sec = 0; - ts.tv_nsec = 0; - tp = &ts; + if (timer == NGX_TIMER_INFINITE) { + tp = NULL; + expire = 0; - } else if (timer) { + } else { ts.tv_sec = timer / 1000; ts.tv_nsec = (timer % 1000) * 1000000; tp = &ts; - - } else { - tp = NULL; - expire = 0; } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, @@ -427,7 +436,7 @@ static ngx_int_t ngx_kqueue_process_even return NGX_ERROR; } - if (timer) { + if (timer != NGX_TIMER_INFINITE) { delta = ngx_elapsed_msec - delta; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, @@ -550,6 +559,8 @@ static ngx_int_t ngx_kqueue_process_even ngx_accept_mutex_unlock(); + /* TODO: wake up worker thread */ + if (expire && delta) { ngx_event_expire_timers((ngx_msec_t) delta); } diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -277,14 +277,22 @@ int ngx_poll_process_events(ngx_cycle_t expire = 0; } else { - timer = ngx_event_find_timer(); + for ( ;; ) { + timer = ngx_event_find_timer(); + + if (timer != 0) { + break; + } - if (timer == -1) { - timer = 0; - expire = 1; + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "poll expired timer"); - } else if (timer == 0) { - timer = (ngx_msec_t) INFTIM; + ngx_event_expire_timers(0); + } + + /* NGX_TIMER_INFINITE == INFTIM */ + + if (timer == NGX_TIMER_INFINITE) { expire = 0; } else { @@ -308,7 +316,7 @@ int ngx_poll_process_events(ngx_cycle_t } if (ngx_accept_mutex_held == 0 - && (timer == (ngx_msec_t) INFTIM || timer > ngx_accept_mutex_delay)) + && (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay)) { timer = ngx_accept_mutex_delay; expire = 0; @@ -341,7 +349,7 @@ int ngx_poll_process_events(ngx_cycle_t return NGX_ERROR; } - if (timer != (ngx_msec_t) INFTIM) { + if (timer != NGX_TIMER_INFINITE) { delta = ngx_elapsed_msec - delta; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 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 @@ -192,6 +192,7 @@ int ngx_rtsig_process_events(ngx_cycle_t { int signo; ngx_int_t instance, i; + ngx_uint_t expire; size_t n; ngx_msec_t timer; ngx_err_t err; @@ -199,21 +200,49 @@ int ngx_rtsig_process_events(ngx_cycle_t struct timeval tv; struct timespec ts, *tp; struct sigaction sa; + ngx_epoch_msec_t delta; ngx_connection_t *c; - ngx_epoch_msec_t delta; ngx_rtsig_conf_t *rtscf; - timer = ngx_event_find_timer(); - ngx_old_elapsed_msec = ngx_elapsed_msec; + for ( ;; ) { + timer = ngx_event_find_timer(); + + if (timer != 0) { + break; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "rtsig expired timer"); + + ngx_event_expire_timers(0); + } + + expire = 1; - if (timer) { + if (ngx_accept_mutex) { + if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { + return NGX_ERROR; + } + + if (ngx_accept_mutex_held == 0 + && (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay)) + { + timer = ngx_accept_mutex_delay; + expire = 0; + } + } + + if (timer == NGX_TIMER_INFINITE) { + tp = NULL; + expire = 0; + + } else { ts.tv_sec = timer / 1000; ts.tv_nsec = (timer % 1000) * 1000000; tp = &ts; + } - } else { - tp = NULL; - } + ngx_old_elapsed_msec = ngx_elapsed_msec; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "rtsig timer: %d", timer); @@ -237,10 +266,11 @@ int ngx_rtsig_process_events(ngx_cycle_t if (err) { ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, cycle->log, err, "sigtimedwait() failed"); + ngx_accept_mutex_unlock(); return NGX_ERROR; } - if (timer) { + if (timer != NGX_TIMER_INFINITE) { delta = ngx_elapsed_msec - delta; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, @@ -263,18 +293,50 @@ int ngx_rtsig_process_events(ngx_cycle_t if (si.si_band & (POLLIN|POLLHUP|POLLERR)) { if (c->read->active) { c->read->ready = 1; - c->read->event_handler(c->read); + + if (!ngx_threaded && !ngx_accept_mutex_held) { + c->read->event_handler(c->read); + + } else if (c->read->accept) { + c->read->event_handler(c->read); + + } else { + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + ngx_accept_mutex_unlock(); + return NGX_ERROR; + } + + ngx_post_event(c->read); + + ngx_mutex_unlock(ngx_posted_events_mutex); + } } } if (si.si_band & (POLLOUT|POLLHUP|POLLERR)) { if (c->write->active) { c->write->ready = 1; - c->write->event_handler(c->write); + + if (!ngx_threaded && !ngx_accept_mutex_held) { + c->write->event_handler(c->write); + + } else { + + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + ngx_accept_mutex_unlock(); + return NGX_ERROR; + } + + ngx_post_event(c->write); + + ngx_mutex_unlock(ngx_posted_events_mutex); + } } } } else if (signo == SIGIO) { + ngx_accept_mutex_unlock(); + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "signal queue overflowed: " "SIGIO, fd:%d, band:%X", si.si_fd, si.si_band); @@ -300,13 +362,21 @@ int ngx_rtsig_process_events(ngx_cycle_t } else { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "sigtimedwait() returned unexpected signal: %d", signo); + ngx_accept_mutex_unlock(); return NGX_ERROR; } - if (timer != (ngx_msec_t) -1 && delta) { + + ngx_accept_mutex_unlock(); + + if (expire && delta) { ngx_event_expire_timers((ngx_msec_t) delta); } + if (!ngx_threaded) { + ngx_event_process_posted(cycle); + } + return NGX_OK; } diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -263,7 +263,19 @@ static int ngx_select_process_events(ngx static ngx_epoch_msec_t deltas = 0; #endif - timer = ngx_event_find_timer(); + for ( ;; ) { + timer = ngx_event_find_timer(); + + if (timer != 0) { + break; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "select expired timer"); + + ngx_event_expire_timers(0); + } + ngx_old_elapsed_msec = ngx_elapsed_msec; expire = 1; @@ -276,7 +288,7 @@ static int ngx_select_process_events(ngx } if (ngx_accept_mutex_held == 0 - && (timer == 0 || timer > ngx_accept_mutex_delay)) + && (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay)) { timer = ngx_accept_mutex_delay; expire = 0; @@ -306,19 +318,14 @@ static int ngx_select_process_events(ngx } #endif - if (timer == -1) { - tv.tv_sec = 0; - tv.tv_usec = 0; - tp = &tv; + if (timer == NGX_TIMER_INFINITE) { + tp = NULL; + expire = 0; - } else if (timer) { + } else { tv.tv_sec = timer / 1000; tv.tv_usec = (timer % 1000) * 1000; tp = &tv; - - } else { - tp = NULL; - expire = 0; } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, @@ -344,7 +351,7 @@ static int ngx_select_process_events(ngx #if (HAVE_SELECT_CHANGE_TIMEOUT) - if (timer) { + if (timer != NGX_TIMER_INFINITE) { delta = timer - (tv.tv_sec * 1000 + tv.tv_usec / 1000); /* @@ -383,7 +390,7 @@ static int ngx_select_process_events(ngx delta = ngx_elapsed_msec; ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; - if (timer) { + if (timer != NGX_TIMER_INFINITE) { delta = ngx_elapsed_msec - delta; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 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 @@ -40,7 +40,7 @@ ngx_msec_t ngx_event_find_timer(void) ngx_rbtree_t *node; if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) { - return 0; + return NGX_TIMER_INFINITE; } if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) { @@ -59,7 +59,7 @@ ngx_msec_t ngx_event_find_timer(void) (node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec); #endif - return timer > 0 ? timer: -1 ; + return timer > 0 ? timer: 0 ; } @@ -83,7 +83,7 @@ void ngx_event_expire_timers(ngx_msec_t ngx_mutex_unlock(ngx_event_timer_mutex); - if ((ngx_msec_t) node->key <= (ngx_msec_t) + if (node->key <= (ngx_msec_t) (ngx_old_elapsed_msec + timer) / NGX_TIMER_RESOLUTION) { ev = (ngx_event_t *) 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 @@ -7,7 +7,8 @@ #include -#define NGX_TIMER_ERROR (ngx_msec_t) -1 +#define NGX_TIMER_INFINITE -1 +#define NGX_TIMER_ERROR -2 /* * 32 bit timer key value resolution diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -93,4 +93,8 @@ extern ssize_t sendfile(int s, int fd, i #define ngx_setproctitle(title) +/* STUB */ +#define HAVE_LITTLE_ENDIAN 1 + + #endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h --- a/src/os/unix/ngx_solaris_config.h +++ b/src/os/unix/ngx_solaris_config.h @@ -26,7 +26,6 @@ #include #include #include /* FIONBIO */ -#include /* INFTIM */ #include #include #include @@ -75,4 +74,8 @@ #define ngx_setproctitle(title) +/* STUB */ +#define HAVE_LITTLE_ENDIAN 1 + + #endif /* _NGX_SOLARIS_CONFIG_H_INCLUDED_ */