# HG changeset patch # User Igor Sysoev # Date 1082573673 0 # Node ID ba876b26b76dfdb279d1413002393e9dbb70a549 # Parent ab2f8c9a2a456cf2f3533924f408065b8985ec51 nginx-0.0.3-2004-04-21-22:54:33 import diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -123,3 +123,9 @@ if [ $help = yes ]; then exit 1 fi + + +if [ ".$PLATFORM" = ".win32" -a $EVENT_POLL = YES ]; then + EVENT_POLL=NO + echo "$0: warning: --with-poll_module option is ignored for win32" +fi diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -86,7 +86,7 @@ int main(int argc, char *const *argv) ngx_core_conf_t *ccf; ngx_master_ctx_t ctx; -#if __FreeBSD__ +#if defined __FreeBSD__ ngx_debug_init(); #endif 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 @@ -2,29 +2,22 @@ #define _NGX_CONFIG_H_INCLUDED_ -#if 0 -/* STUB to allocate a big ngx_connections */ -#undef FD_SETSIZE -#define FD_SETSIZE 5000 -#endif - - -#if defined __DragonFly__ && !defined(__FreeBSD__) +#if defined __DragonFly__ && !defined __FreeBSD__ #define __FreeBSD__ 4 #define __FreeBSD_version 480101 #endif -#if defined (__FreeBSD__) +#if defined __FreeBSD__ #include -#elif defined (__linux__) +#elif defined __linux__ #include /* Solaris */ -#elif defined (sun) && (defined (__svr4__) || defined (__SVR4)) +#elif defined sun && (defined __svr4__ || defined __SVR4) #include @@ -101,6 +94,8 @@ typedef int ngx_flag_t; #define ngx_inline inline #endif +#define NGX_ACCEPT_THRESHOLD 50 + #ifndef INADDR_NONE /* Solaris */ #define INADDR_NONE ((unsigned int) -1) #endif 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 @@ -8,21 +8,27 @@ static ngx_mutex_t *ngx_time_mutex; #endif -time_t ngx_cached_time; -ngx_epoch_msec_t ngx_elapsed_msec; -ngx_epoch_msec_t ngx_old_elapsed_msec; -ngx_epoch_msec_t ngx_start_msec; +ngx_epoch_msec_t ngx_elapsed_msec; +ngx_epoch_msec_t ngx_old_elapsed_msec; +ngx_epoch_msec_t ngx_start_msec; -ngx_tm_t ngx_cached_gmtime; +volatile time_t ngx_cached_time; + +volatile ngx_str_t ngx_cached_err_log_time; +volatile ngx_str_t ngx_cached_http_time; +volatile ngx_str_t ngx_cached_http_log_time; -static u_char cached_err_log_time[] = "1970/09/28 12:00:00"; -ngx_str_t ngx_cached_err_log_time; +static ngx_tm_t ngx_cached_gmtime; +static ngx_int_t ngx_gmtoff; + +static u_char cached_err_log_time0[] = "1970/09/28 12:00:00"; +static u_char cached_err_log_time1[] = "1970/09/28 12:00:00"; -static u_char cached_http_time[] = "Mon, 28 Sep 1970 06:00:00 GMT"; -ngx_str_t ngx_cached_http_time; +static u_char cached_http_time0[] = "Mon, 28 Sep 1970 06:00:00 GMT"; +static u_char cached_http_time1[] = "Mon, 28 Sep 1970 06:00:00 GMT"; -static u_char cached_http_log_time[] = "28/Sep/1970:12:00:00"; -ngx_str_t ngx_cached_http_log_time; +static u_char cached_http_log_time0[] = "28/Sep/1970:12:00:00 +0600"; +static u_char cached_http_log_time1[] = "28/Sep/1970:12:00:00 +0600"; static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fir", "Sat" }; @@ -39,9 +45,15 @@ void ngx_time_init() ngx_cached_gmtime.ngx_tm_zone = "GMT"; #endif - ngx_cached_err_log_time.data = cached_err_log_time; - ngx_cached_http_time.data = cached_http_time; - ngx_cached_http_log_time.data = cached_http_log_time; + ngx_cached_err_log_time.len = sizeof(cached_err_log_time0) - 1; + ngx_cached_err_log_time.data = cached_err_log_time0; + + ngx_cached_http_time.len = sizeof(cached_http_time0) - 1; + ngx_cached_http_time.data = cached_http_time0; + + ngx_cached_http_log_time.len = sizeof(cached_http_log_time0) - 1; + ngx_cached_http_log_time.data = cached_http_log_time0; + ngx_cached_time = 0; ngx_gettimeofday(&tv); @@ -50,6 +62,10 @@ void ngx_time_init() ngx_old_elapsed_msec = 0; ngx_elapsed_msec = 0; +#if !(WIN32) + tzset(); +#endif + ngx_time_update(tv.tv_sec); } @@ -70,7 +86,11 @@ ngx_int_t ngx_time_mutex_init(ngx_log_t void ngx_time_update(time_t s) { - ngx_tm_t tm; + char *p; + ngx_tm_t tm; +#if (WIN32) + TIME_ZONE_INFORMATION tz; +#endif if (ngx_cached_time == s) { return; @@ -86,37 +106,88 @@ void ngx_time_update(time_t s) ngx_gmtime(ngx_cached_time, &ngx_cached_gmtime); - ngx_cached_http_time.len = ngx_snprintf((char *) ngx_cached_http_time.data, - sizeof("Mon, 28 Sep 1970 06:00:00 GMT"), - "%s, %02d %s %4d %02d:%02d:%02d GMT", - week[ngx_cached_gmtime.ngx_tm_wday], - ngx_cached_gmtime.ngx_tm_mday, - months[ngx_cached_gmtime.ngx_tm_mon - 1], - ngx_cached_gmtime.ngx_tm_year, - ngx_cached_gmtime.ngx_tm_hour, - ngx_cached_gmtime.ngx_tm_min, - ngx_cached_gmtime.ngx_tm_sec); + + if (ngx_cached_http_time.data == cached_http_time0) { + p = cached_http_time1; + } else { + p = cached_http_time0; + } + + ngx_snprintf(p, sizeof("Mon, 28 Sep 1970 06:00:00 GMT"), + "%s, %02d %s %4d %02d:%02d:%02d GMT", + week[ngx_cached_gmtime.ngx_tm_wday], + ngx_cached_gmtime.ngx_tm_mday, + months[ngx_cached_gmtime.ngx_tm_mon - 1], + ngx_cached_gmtime.ngx_tm_year, + ngx_cached_gmtime.ngx_tm_hour, + ngx_cached_gmtime.ngx_tm_min, + ngx_cached_gmtime.ngx_tm_sec); + + ngx_cached_http_time.data = p; + + +#if (WIN32) + + /* + * we do not use GetLocalTime() because it does not return GMT offset, + * and our ngx_gmtime() is fast enough + */ + + if (GetTimeZoneInformation(&tz) != TIME_ZONE_ID_INVALID) { + ngx_gmtoff = - tz.Bias; + } + + ngx_gmtime(ngx_cached_time + ngx_gmtoff * 60, &tm); + +#elif (SOLARIS) + + ngx_gmtoff = (daylight) ? - altzone / 60: - timezone / 60; + ngx_gmtime(ngx_cached_time + ngx_gmtoff * 60, &tm); + +#elif defined __linux__ + + ngx_gmtoff = - timezone / 60 + daylight * 60; + ngx_gmtime(ngx_cached_time + ngx_gmtoff * 60, &tm); + +#else ngx_localtime(&tm); + ngx_gmtoff = tm.ngx_tm_gmtoff / 60; - ngx_cached_err_log_time.len = ngx_snprintf((char *) - ngx_cached_err_log_time.data, - sizeof("1970/09/28 12:00:00"), - "%4d/%02d/%02d %02d:%02d:%02d", - tm.ngx_tm_year, tm.ngx_tm_mon, - tm.ngx_tm_mday, tm.ngx_tm_hour, - tm.ngx_tm_min, tm.ngx_tm_sec); +#endif + + + if (ngx_cached_err_log_time.data == cached_err_log_time0) { + p = cached_err_log_time1; + } else { + p = cached_err_log_time0; + } + + ngx_snprintf(p, sizeof("1970/09/28 12:00:00"), + "%4d/%02d/%02d %02d:%02d:%02d", + tm.ngx_tm_year, tm.ngx_tm_mon, + tm.ngx_tm_mday, tm.ngx_tm_hour, + tm.ngx_tm_min, tm.ngx_tm_sec); - ngx_cached_http_log_time.len = ngx_snprintf((char *) - ngx_cached_http_log_time.data, - sizeof("28/Sep/1970:12:00:00"), - "%02d/%s/%d:%02d:%02d:%02d", - tm.ngx_tm_mday, - months[tm.ngx_tm_mon - 1], - tm.ngx_tm_year, - tm.ngx_tm_hour, - tm.ngx_tm_min, - tm.ngx_tm_sec); + ngx_cached_err_log_time.data = p; + + + if (ngx_cached_http_log_time.data == cached_http_log_time0) { + p = cached_http_log_time1; + } else { + p = cached_http_log_time0; + } + + ngx_snprintf(p, sizeof("28/Sep/1970:12:00:00 +0600"), + "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d", + tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1], + tm.ngx_tm_year, tm.ngx_tm_hour, + tm.ngx_tm_min, tm.ngx_tm_sec, + ngx_gmtoff < 0 ? '-' : '+', + abs(ngx_gmtoff / 60), abs(ngx_gmtoff % 60)); + + ngx_cached_http_log_time.data = p; + #if (NGX_THREADS) ngx_mutex_unlock(ngx_time_mutex); diff --git a/src/core/ngx_times.h b/src/core/ngx_times.h --- a/src/core/ngx_times.h +++ b/src/core/ngx_times.h @@ -17,12 +17,12 @@ void ngx_gmtime(time_t t, ngx_tm_t *tp); #define ngx_time() ngx_cached_time -extern time_t ngx_cached_time; -extern ngx_str_t ngx_cached_err_log_time; -extern ngx_str_t ngx_cached_http_time; -extern ngx_str_t ngx_cached_http_log_time; +extern volatile time_t ngx_cached_time; +extern volatile ngx_str_t ngx_cached_err_log_time; +extern volatile ngx_str_t ngx_cached_http_time; +extern volatile ngx_str_t ngx_cached_http_log_time; -extern ngx_epoch_msec_t ngx_start_msec; +extern ngx_epoch_msec_t ngx_start_msec; /* * msecs elapsed since ngx_start_msec in the current event cycle, 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 @@ -313,7 +313,7 @@ int ngx_devpoll_process_events(ngx_cycle { int events; ngx_int_t i; - ngx_uint_t j, lock, expire; + ngx_uint_t j, lock, accept_lock, expire; size_t n; ngx_msec_t timer; ngx_err_t err; @@ -346,21 +346,30 @@ int ngx_devpoll_process_events(ngx_cycle expire = 1; } + ngx_old_elapsed_msec = ngx_elapsed_msec; + accept_lock = 0; + if (ngx_accept_mutex) { - if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { - return NGX_ERROR; - } + if (ngx_accept_disabled > 0) { + ngx_accept_disabled--; - if (ngx_accept_mutex_held == 0 - && (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay)) - { - timer = ngx_accept_mutex_delay; - expire = 0; + } else { + if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { + return NGX_ERROR; + } + + if (ngx_accept_mutex_held) { + accept_lock = 1; + + } else if (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); @@ -493,30 +502,39 @@ int ngx_devpoll_process_events(ngx_cycle } else if (!c->read->accept) { ngx_post_event(c->read); - } else { + } else if (ngx_accept_disabled <= 0) { ngx_mutex_unlock(ngx_posted_events_mutex); c->read->event_handler(c->read); + if (ngx_accept_disabled > 0) { + ngx_accept_mutex_unlock(); + accept_lock = 0; + } + if (i + 1 == events) { lock = 0; break; } if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { - ngx_accept_mutex_unlock(); + if (accept_lock) { + ngx_accept_mutex_unlock(); + } return NGX_ERROR; } } } } + if (accept_lock) { + ngx_accept_mutex_unlock(); + } + if (lock) { ngx_mutex_unlock(ngx_posted_events_mutex); } - ngx_accept_mutex_unlock(); - if (expire && delta) { ngx_event_expire_timers((ngx_msec_t) delta); } 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 @@ -345,7 +345,7 @@ int ngx_epoll_process_events(ngx_cycle_t int events; size_t n; ngx_int_t instance, i; - ngx_uint_t lock, expire; + ngx_uint_t lock, accept_lock, expire; ngx_err_t err; ngx_log_t *log; ngx_msec_t timer; @@ -377,17 +377,26 @@ int ngx_epoll_process_events(ngx_cycle_t } ngx_old_elapsed_msec = ngx_elapsed_msec; + accept_lock = 0; if (ngx_accept_mutex) { - if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { - return NGX_ERROR; - } + if (ngx_accept_disabled > 0) { + ngx_accept_disabled--; + + } else { + 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 (ngx_accept_mutex_held) { + accept_lock = 1; + + } else if (timer == NGX_TIMER_INFINITE + || timer > ngx_accept_mutex_delay) + { + timer = ngx_accept_mutex_delay; + expire = 0; + } } } @@ -513,30 +522,40 @@ int ngx_epoll_process_events(ngx_cycle_t } else if (!c->read->accept) { ngx_post_event(c->read); - } else { + } else if (ngx_accept_disabled <= 0) { + ngx_mutex_unlock(ngx_posted_events_mutex); c->read->event_handler(c->read); + if (ngx_accept_disabled > 0) { + ngx_accept_mutex_unlock(); + accept_lock = 0; + } + if (i + 1 == events) { lock = 0; break; } if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { - ngx_accept_mutex_unlock(); + if (accept_lock) { + ngx_accept_mutex_unlock(); + } return NGX_ERROR; } } } } + if (accept_lock) { + ngx_accept_mutex_unlock(); + } + if (lock) { ngx_mutex_unlock(ngx_posted_events_mutex); } - ngx_accept_mutex_unlock(); - if (expire && delta) { ngx_event_expire_timers((ngx_msec_t) delta); } 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 @@ -345,7 +345,7 @@ static ngx_int_t ngx_kqueue_process_even { int events; ngx_int_t i, instance; - ngx_uint_t lock, expire; + ngx_uint_t lock, accept_lock, expire; ngx_err_t err; ngx_msec_t timer; ngx_event_t *ev; @@ -384,17 +384,26 @@ static ngx_int_t ngx_kqueue_process_even ngx_old_elapsed_msec = ngx_elapsed_msec; expire = 1; + accept_lock = 0; if (ngx_accept_mutex) { - if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { - return NGX_ERROR; - } + if (ngx_accept_disabled > 0) { + ngx_accept_disabled--; + + } else { + 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 (ngx_accept_mutex_held) { + accept_lock = 1; + + } else if (timer == NGX_TIMER_INFINITE + || timer > ngx_accept_mutex_delay) + { + timer = ngx_accept_mutex_delay; + expire = 0; + } } } @@ -539,27 +548,40 @@ static ngx_int_t ngx_kqueue_process_even continue; } + if (ngx_accept_disabled > 0) { + continue; + } + ngx_mutex_unlock(ngx_posted_events_mutex); ev->event_handler(ev); + if (ngx_accept_disabled > 0) { + ngx_accept_mutex_unlock(); + accept_lock = 0; + } + if (i + 1 == events) { lock = 0; break; } if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { - ngx_accept_mutex_unlock(); + if (accept_lock) { + ngx_accept_mutex_unlock(); + } return NGX_ERROR; } } + if (accept_lock) { + ngx_accept_mutex_unlock(); + } + if (lock) { ngx_mutex_unlock(ngx_posted_events_mutex); } - ngx_accept_mutex_unlock(); - /* TODO: wake up worker thread */ if (expire && 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 @@ -304,23 +304,31 @@ int ngx_poll_process_events(ngx_cycle_t ngx_old_elapsed_msec = ngx_elapsed_msec; #if (NGX_DEBUG0) - for (i = 0; i < nevents; i++) { - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "poll: %d: fd:%d ev:%04X", - i, event_list[i].fd, event_list[i].events); + if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { + for (i = 0; i < nevents; i++) { + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "poll: %d: fd:%d ev:%04X", + i, event_list[i].fd, event_list[i].events); + } } #endif if (ngx_accept_mutex) { - if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { - return NGX_ERROR; - } + if (ngx_accept_disabled > 0) { + ngx_accept_disabled--; + + } else { + 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 (ngx_accept_mutex_held == 0 + && (timer == NGX_TIMER_INFINITE + || timer > ngx_accept_mutex_delay)) + { + timer = ngx_accept_mutex_delay; + expire = 0; + } } } @@ -543,6 +551,11 @@ int ngx_poll_process_events(ngx_cycle_t ev->event_handler(ev); + if (ngx_accept_disabled > 0) { + lock = 0; + break; + } + ev = ev->next; if (ev == NULL) { @@ -557,13 +570,13 @@ int ngx_poll_process_events(ngx_cycle_t } + ngx_accept_mutex_unlock(); + accept_events = NULL; + if (lock) { ngx_mutex_unlock(ngx_posted_events_mutex); } - ngx_accept_mutex_unlock(); - accept_events = NULL; - if (ready != 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events"); } 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 @@ -221,15 +221,21 @@ int ngx_rtsig_process_events(ngx_cycle_t expire = 1; if (ngx_accept_mutex) { - if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { - return NGX_ERROR; - } + if (ngx_accept_disabled > 0) { + ngx_accept_disabled--; + + } else { + 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 (ngx_accept_mutex_held == 0 + && (timer == NGX_TIMER_INFINITE + || timer > ngx_accept_mutex_delay)) + { + timer = ngx_accept_mutex_delay; + expire = 0; + } } } @@ -299,7 +305,9 @@ int ngx_rtsig_process_events(ngx_cycle_t c->read->event_handler(c->read); } else if (c->read->accept) { - c->read->event_handler(c->read); + if (ngx_accept_disabled > 0) { + c->read->event_handler(c->read); + } } else { if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { @@ -367,7 +375,6 @@ int ngx_rtsig_process_events(ngx_cycle_t return NGX_ERROR; } - ngx_accept_mutex_unlock(); if (expire && delta) { 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 @@ -284,15 +284,21 @@ static int ngx_select_process_events(ngx #if !(WIN32) if (ngx_accept_mutex) { - if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { - return NGX_ERROR; - } + if (ngx_accept_disabled > 0) { + ngx_accept_disabled--; + + } else { + 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 (ngx_accept_mutex_held == 0 + && (timer == NGX_TIMER_INFINITE + || timer > ngx_accept_mutex_delay)) + { + timer = ngx_accept_mutex_delay; + expire = 0; + } } } @@ -311,11 +317,18 @@ static int ngx_select_process_events(ngx #endif #if (NGX_DEBUG) - for (i = 0; i < nevents; i++) { - ev = event_index[i]; - c = ev->data; - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select event: fd:%d wr:%d", c->fd, ev->write); + if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { + for (i = 0; i < nevents; i++) { + ev = event_index[i]; + c = ev->data; + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "select event: fd:%d wr:%d", c->fd, ev->write); + } + +#if !(WIN32) + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "max_fd: %d", max_fd); +#endif } #endif @@ -365,6 +378,11 @@ static int ngx_select_process_events(ngx ngx_gettimeofday(&tv); ngx_time_update(tv.tv_sec); deltas = tv.tv_usec / 1000; + + ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 + - ngx_start_msec; + } else { + ngx_elapsed_msec += delta; } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, @@ -375,6 +393,8 @@ static int ngx_select_process_events(ngx ngx_gettimeofday(&tv); ngx_time_update(tv.tv_sec); + ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 + - ngx_start_msec; if (ready == 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select() returned no events without timeout"); @@ -523,6 +543,11 @@ static int ngx_select_process_events(ngx ev->event_handler(ev); + if (ngx_accept_disabled > 0) { + lock = 0; + break; + } + ev = ev->next; if (ev == NULL) { @@ -534,16 +559,15 @@ static int ngx_select_process_events(ngx ngx_accept_mutex_unlock(); return NGX_ERROR; } + } - } + ngx_accept_mutex_unlock(); + accept_events = NULL; if (lock) { ngx_mutex_unlock(ngx_posted_events_mutex); } - ngx_accept_mutex_unlock(); - accept_events = NULL; - if (ready != nready) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select ready != events"); } 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 @@ -56,6 +56,7 @@ ngx_atomic_t *ngx_ac 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; @@ -464,13 +465,13 @@ static char *ngx_event_connections(ngx_c ngx_str_t *value; - if (ecf->connections != NGX_CONF_UNSET) { + if (ecf->connections != NGX_CONF_UNSET_UINT) { return "is duplicate" ; } value = cf->args->elts; ecf->connections = ngx_atoi(value[1].data, value[1].len); - if (ecf->connections == NGX_ERROR) { + if (ecf->connections == (ngx_uint_t) NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number \"%s\"", value[1].data); @@ -598,7 +599,7 @@ static void *ngx_event_create_conf(ngx_c ngx_test_null(ecf, ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t)), NGX_CONF_ERROR); - ecf->connections = NGX_CONF_UNSET; + ecf->connections = NGX_CONF_UNSET_UINT; ecf->use = NGX_CONF_UNSET; ecf->multi_accept = NGX_CONF_UNSET; ecf->accept_mutex = NGX_CONF_UNSET; @@ -620,25 +621,25 @@ static char *ngx_event_init_conf(ngx_cyc #if (HAVE_KQUEUE) - ngx_conf_init_value(ecf->connections, DEFAULT_CONNECTIONS); + ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS); ngx_conf_init_value(ecf->use, ngx_kqueue_module.ctx_index); ngx_conf_init_ptr_value(ecf->name, ngx_kqueue_module_ctx.name->data); #elif (HAVE_DEVPOLL) - ngx_conf_init_value(ecf->connections, DEFAULT_CONNECTIONS); + ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS); ngx_conf_init_value(ecf->use, ngx_devpoll_module.ctx_index); ngx_conf_init_ptr_value(ecf->name, ngx_devpoll_module_ctx.name->data); #elif (HAVE_EPOLL) - ngx_conf_init_value(ecf->connections, DEFAULT_CONNECTIONS); + ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS); ngx_conf_init_value(ecf->use, ngx_epoll_module.ctx_index); ngx_conf_init_ptr_value(ecf->name, ngx_epoll_module_ctx.name->data); #elif (HAVE_SELECT) - ngx_conf_init_value(ecf->connections, + ngx_conf_init_unsigned_value(ecf->connections, FD_SETSIZE < DEFAULT_CONNECTIONS ? FD_SETSIZE : DEFAULT_CONNECTIONS); ngx_conf_init_value(ecf->use, ngx_select_module.ctx_index); 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 @@ -381,7 +381,7 @@ extern ngx_event_actions_t ngx_event_a typedef struct { - ngx_int_t connections; + ngx_uint_t connections; ngx_int_t use; ngx_flag_t multi_accept; @@ -413,6 +413,7 @@ extern ngx_atomic_t *ngx_accept extern ngx_atomic_t *ngx_accept_mutex; extern ngx_uint_t ngx_accept_mutex_held; extern ngx_msec_t ngx_accept_mutex_delay; +extern ngx_int_t ngx_accept_disabled; #define ngx_accept_mutex_unlock() \ 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 @@ -125,9 +125,13 @@ void ngx_event_accept(ngx_event_t *ev) return; } + + ngx_accept_disabled = (ngx_uint_t) s + NGX_ACCEPT_THRESHOLD + - ecf->connections; + /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ - if ((unsigned) s >= (unsigned) ecf->connections) { + if ((ngx_uint_t) s >= ecf->connections) { ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "accept() on %s returned socket #%d while " @@ -140,8 +144,6 @@ void ngx_event_accept(ngx_event_t *ev) ngx_close_socket_n "failed"); } - /* TODO: disable temporary accept() event */ - ngx_destroy_pool(pool); return; } diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -19,6 +19,7 @@ int ngx_event_connect_peer(ngx_peer_conn ngx_socket_t s; ngx_event_t *rev, *wev; ngx_connection_t *c; + ngx_event_conf_t *ecf; struct sockaddr_in addr; now = ngx_time(); @@ -103,6 +104,29 @@ int ngx_event_connect_peer(ngx_peer_conn return NGX_ERROR; } + + ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); + + /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ + + if ((ngx_uint_t) s >= ecf->connections) { + + ngx_log_error(NGX_LOG_ALERT, pc->log, 0, + "socket() returned socket #%d while only %d " + "connections was configured, closing the socket", + s, ecf->connections); + + if (ngx_close_socket(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + ngx_close_socket_n "failed"); + } + + /* TODO: sleep for some time */ + + return NGX_ERROR; + } + + if (pc->rcvbuf) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const void *) &pc->rcvbuf, sizeof(int)) == -1) { diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c --- a/src/http/modules/ngx_http_gzip_filter.c +++ b/src/http/modules/ngx_http_gzip_filter.c @@ -495,6 +495,9 @@ static int ngx_http_gzip_body_filter(ngx && ctx->flush == Z_NO_FLUSH && !ctx->redo) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "gzip in: " PTR_FMT, ctx->in); + if (ctx->in == NULL) { break; } @@ -505,6 +508,18 @@ static int ngx_http_gzip_body_filter(ngx ctx->zstream.next_in = ctx->in_hunk->pos; ctx->zstream.avail_in = ctx->in_hunk->last - ctx->in_hunk->pos; + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "gzip in_hunk:" PTR_FMT " ni:" PTR_FMT " ai:%d", + ctx->in_hunk, + ctx->zstream.next_in, ctx->zstream.avail_in); + + /* STUB */ + if (ctx->in_hunk->last < ctx->in_hunk->pos) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "zstream.avail_in is huge"); + return NGX_ERROR; + } + if (ctx->in_hunk->type & NGX_HUNK_LAST) { ctx->flush = Z_FINISH; @@ -547,11 +562,11 @@ static int ngx_http_gzip_body_filter(ngx ctx->zstream.avail_out = conf->bufs.size; } - ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "deflate in: ni:%X no:%X ai:%d ao:%d fl:%d", + ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "deflate in: ni:%X no:%X ai:%d ao:%d fl:%d redo:%d", ctx->zstream.next_in, ctx->zstream.next_out, ctx->zstream.avail_in, ctx->zstream.avail_out, - ctx->flush); + ctx->flush, ctx->redo); rc = deflate(&ctx->zstream, ctx->flush); if (rc != Z_OK && rc != Z_STREAM_END) { @@ -566,6 +581,10 @@ static int ngx_http_gzip_body_filter(ngx ctx->zstream.avail_in, ctx->zstream.avail_out, rc); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "gzip in_hunk:" PTR_FMT " pos:" PTR_FMT, + ctx->in_hunk, ctx->in_hunk->pos); + ctx->in_hunk->pos = ctx->zstream.next_in; ctx->out_hunk->last = ctx->zstream.next_out; @@ -576,95 +595,112 @@ static int ngx_http_gzip_body_filter(ngx ctx->last_out = &cl->next; ctx->redo = 1; - } else { - ctx->redo = 0; + continue; + } - if (ctx->flush == Z_SYNC_FLUSH) { - ctx->out_hunk->type |= NGX_HUNK_FLUSH; - ctx->flush = Z_NO_FLUSH; + ctx->redo = 0; + + if (ctx->flush == Z_SYNC_FLUSH) { + ctx->out_hunk->type |= NGX_HUNK_FLUSH; + ctx->flush = Z_NO_FLUSH; - ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, - ngx_http_gzip_error(ctx)); - *ctx->last_out = cl; - ctx->last_out = &cl->next; + ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, + ngx_http_gzip_error(ctx)); + *ctx->last_out = cl; + ctx->last_out = &cl->next; - break; + break; + } + + if (ctx->flush == Z_FINISH) { - } else if (ctx->flush == Z_FINISH) { + /* rc == Z_STREAM_END */ + + ctx->zin = ctx->zstream.total_in; + ctx->zout = 10 + ctx->zstream.total_out + 8; - /* rc == Z_STREAM_END */ + rc = deflateEnd(&ctx->zstream); + if (rc != Z_OK) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "deflateEnd() failed: %d", rc); + return ngx_http_gzip_error(ctx); + } - ctx->zin = ctx->zstream.total_in; - ctx->zout = 10 + ctx->zstream.total_out + 8; + ngx_pfree(r->pool, ctx->preallocated); + + ctx->flush = Z_NO_FLUSH; - rc = deflateEnd(&ctx->zstream); - if (rc != Z_OK) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "deflateEnd() failed: %d", rc); - return ngx_http_gzip_error(ctx); - } + ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, + ngx_http_gzip_error(ctx)); + *ctx->last_out = cl; + ctx->last_out = &cl->next; - ngx_pfree(r->pool, ctx->preallocated); + if (ctx->zstream.avail_out >= 8) { + trailer = (struct gztrailer *) ctx->out_hunk->last; + ctx->out_hunk->type |= NGX_HUNK_LAST; + ctx->out_hunk->last += 8; - ctx->flush = Z_NO_FLUSH; + } else { + ngx_test_null(h, ngx_create_temp_hunk(r->pool, 8), + ngx_http_gzip_error(ctx)); - ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, + h->type |= NGX_HUNK_LAST; + + ngx_alloc_link_and_set_hunk(cl, h, r->pool, ngx_http_gzip_error(ctx)); *ctx->last_out = cl; ctx->last_out = &cl->next; - - if (ctx->zstream.avail_out >= 8) { - trailer = (struct gztrailer *) ctx->out_hunk->last; - ctx->out_hunk->type |= NGX_HUNK_LAST; - ctx->out_hunk->last += 8; - - } else { - ngx_test_null(h, - ngx_create_temp_hunk(r->pool, 8), - ngx_http_gzip_error(ctx)); - - h->type |= NGX_HUNK_LAST; - - ngx_alloc_link_and_set_hunk(cl, h, r->pool, - ngx_http_gzip_error(ctx)); - *ctx->last_out = cl; - ctx->last_out = &cl->next; - trailer = (struct gztrailer *) h->pos; - h->last += 8; - } + trailer = (struct gztrailer *) h->pos; + h->last += 8; + } #if (HAVE_LITTLE_ENDIAN) - trailer->crc32 = ctx->crc32; - trailer->zlen = ctx->zin; + trailer->crc32 = ctx->crc32; + trailer->zlen = ctx->zin; #else - /* STUB */ Oops ! + /* STUB */ Oops ! #endif - ctx->zstream.avail_in = 0; - ctx->zstream.avail_out = 0; + ctx->zstream.avail_in = 0; + ctx->zstream.avail_out = 0; - ctx->done = 1; + ctx->done = 1; #if 0 - ngx_http_delete_ctx(r, ngx_http_gzip_filter_module); + ngx_http_delete_ctx(r, ngx_http_gzip_filter_module); #endif - break; + break; + } - } else if (conf->no_buffer && ctx->in == NULL) { - ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, - ngx_http_gzip_error(ctx)); - *ctx->last_out = cl; - ctx->last_out = &cl->next; + if (conf->no_buffer && ctx->in == NULL) { + ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, + ngx_http_gzip_error(ctx)); + *ctx->last_out = cl; + ctx->last_out = &cl->next; - break; - } + break; } } + if (ctx->out) { + if (last == NGX_AGAIN) { + return last; + } + + } else { + if (last == NGX_NONE) { + return NGX_OK; + } + + return last; + } + +#if 0 if (ctx->out == NULL && last != NGX_NONE) { return last; } +#endif last = ngx_http_next_body_filter(r, ctx->out); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1449,7 +1449,8 @@ static char *ngx_set_error_page(ngx_conf { ngx_http_core_loc_conf_t *lcf = conf; - ngx_uint_t i; + int overwrite; + ngx_uint_t i, n; ngx_str_t *value; ngx_http_err_page_t *err; @@ -1463,8 +1464,35 @@ static char *ngx_set_error_page(ngx_conf value = cf->args->elts; - for (i = 1; i < cf->args->nelts - 1; i++) { - ngx_test_null(err, ngx_push_array(lcf->error_pages), NGX_CONF_ERROR); + i = cf->args->nelts - 2; + + if (value[i].data[0] == '=') { + if (i == 1) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid value \"%s\"", value[i].data); + return NGX_CONF_ERROR; + } + + overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1); + + if (overwrite == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid value \"%s\"", value[i].data); + return NGX_CONF_ERROR; + } + + n = 2; + + } else { + overwrite = 0; + n = 1; + } + + for (i = 1; i < cf->args->nelts - n; i++) { + if (!(err = ngx_push_array(lcf->error_pages))) { + return NGX_CONF_ERROR; + } + err->code = ngx_atoi(value[i].data, value[i].len); if (err->code == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -1479,6 +1507,7 @@ static char *ngx_set_error_page(ngx_conf return NGX_CONF_ERROR; } + err->overwrite = overwrite; err->uri = value[cf->args->nelts - 1]; } diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -106,6 +106,7 @@ typedef struct { typedef struct { int code; + int overwrite; ngx_str_t uri; } ngx_http_err_page_t; diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -46,6 +46,10 @@ ngx_int_t ngx_http_parse_request_line(ng case sw_start: r->request_start = p - 1; + if (ch == CR || ch == LF) { + break; + } + if (ch < 'A' || ch > 'Z') { return NGX_HTTP_PARSE_INVALID_METHOD; } 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 @@ -728,8 +728,10 @@ static void ngx_http_process_request_hea /* there was error while a header line parsing */ -#if (NGX_LOG_DEBUG) - if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { +#if (NGX_DEBUG) + if (rc == NGX_HTTP_PARSE_INVALID_HEADER + && (rev->log->log_level & NGX_LOG_DEBUG_HTTP)) + { u_char *p; for (p = r->header_name_start; p < r->header_in->last - 1; @@ -1249,12 +1251,6 @@ static void ngx_http_set_keepalive(ngx_h wev->event_handler = ngx_http_empty_handler; - /* skip the tralling "\r\n" before the possible pipelined request */ - - while (h->pos < h->last && (*h->pos == CR || *h->pos == LF)) { - h->pos++; - } - if (h->pos < h->last) { /* diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -214,7 +214,11 @@ int ngx_http_special_response_handler(ng err_page = clcf->error_pages->elts; for (i = 0; i < clcf->error_pages->nelts; i++) { if (err_page[i].code == error) { - r->err_status = error; + if (err_page[i].overwrite) { + r->err_status = err_page[i].overwrite; + } else { + r->err_status = error; + } r->err_ctx = r->ctx; return ngx_http_internal_redirect(r, &err_page[i].uri, NULL); } 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 @@ -494,6 +494,7 @@ static void ngx_worker_process_cycle(ngx } if (ngx_quit) { + ngx_quit = 0; ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "gracefully shutting down"); ngx_setproctitle("worker process is shutting down"); @@ -505,9 +506,9 @@ static void ngx_worker_process_cycle(ngx } if (ngx_reopen) { + ngx_reopen = 0; ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs"); ngx_reopen_files(cycle, -1); - ngx_reopen = 0; } } } diff --git a/src/os/unix/ngx_time.c b/src/os/unix/ngx_time.c --- a/src/os/unix/ngx_time.c +++ b/src/os/unix/ngx_time.c @@ -7,12 +7,12 @@ void ngx_localtime(ngx_tm_t *tm) { #if (HAVE_LOCALTIME_R) - localtime_r(&ngx_cached_time, tm); + localtime_r((time_t *) &ngx_cached_time, tm); #else ngx_tm_t *t; - t = localtime(&ngx_cached_time); + t = localtime((time_t *) &ngx_cached_time); *tm = *t; #endif diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h --- a/src/os/unix/ngx_time.h +++ b/src/os/unix/ngx_time.h @@ -20,6 +20,7 @@ typedef struct tm ngx_tm_t; #define ngx_tm_mon tm_mon #define ngx_tm_year tm_year #define ngx_tm_wday tm_wday +#define ngx_tm_gmtoff tm_gmtoff #ifndef SOLARIS #define ngx_tm_zone tm_zone @@ -41,7 +42,4 @@ void ngx_localtime(ngx_tm_t *tm); #define ngx_msleep(ms) usleep(ms * 1000) -extern time_t ngx_cached_time; - - #endif /* _NGX_TIME_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_time.h b/src/os/win32/ngx_time.h --- a/src/os/win32/ngx_time.h +++ b/src/os/win32/ngx_time.h @@ -33,7 +33,6 @@ typedef FILETIME ngx_mtime_t; #define ngx_msleep Sleep -#define ngx_localtime GetLocalTime void ngx_gettimeofday(struct timeval *tp);