# HG changeset patch # User Igor Sysoev # Date 1068574423 0 # Node ID 9f3a78b06c48d74a89a77876169d7e38d1785d67 # Parent a8ff48d26cca369c06edd35a4a4307daae5e51d3 nginx-0.0.1-2003-11-11-21:13:43 import 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 @@ -322,9 +322,10 @@ static int ngx_devpoll_set_event(ngx_eve int ngx_devpoll_process_events(ngx_log_t *log) { int events, n, i, j; - ngx_msec_t timer, delta; + ngx_msec_t timer; ngx_err_t err; ngx_cycle_t **cycle; + ngx_epoch_msec_t delta; ngx_connection_t *c; struct dvpoll dvp; struct timeval tv; @@ -332,7 +333,7 @@ int ngx_devpoll_process_events(ngx_log_t timer = ngx_event_find_timer(); if (timer) { - gettimeofday(&tv, NULL); + ngx_gettimeofday(&tv); delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; } else { @@ -366,7 +367,7 @@ int ngx_devpoll_process_events(ngx_log_t nchanges = 0; - gettimeofday(&tv, NULL); + ngx_gettimeofday(&tv); if (ngx_cached_time != tv.tv_sec) { ngx_cached_time = tv.tv_sec; @@ -377,9 +378,9 @@ int ngx_devpoll_process_events(ngx_log_t delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; #if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ delta); + ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ (int)delta); #endif - ngx_event_expire_timers(delta); + ngx_event_expire_timers((ngx_msec_t) delta); } else { if (events == 0) { @@ -389,7 +390,7 @@ int ngx_devpoll_process_events(ngx_log_t } #if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ delta); + ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ (int)delta); #endif } diff --git a/src/event/modules/ngx_iocp_module.c b/src/event/modules/ngx_iocp_module.c --- a/src/event/modules/ngx_iocp_module.c +++ b/src/event/modules/ngx_iocp_module.c @@ -162,14 +162,16 @@ static int ngx_iocp_process_events(ngx_l u_int key; size_t bytes; ngx_err_t err; - ngx_msec_t timer, delta; + ngx_msec_t timer; ngx_event_t *ev; + ngx_epoch_msec_t delta; ngx_event_ovlp_t *ovlp; timer = ngx_event_find_timer(); if (timer) { - delta = ngx_msec(); + ngx_gettimeofday(&tv); + delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; } else { timer = INFINITE; @@ -189,11 +191,16 @@ static int ngx_iocp_process_events(ngx_l err = 0; } - /* TODO: timer */ + ngx_gettimeofday(&tv); + + if (ngx_cached_time != tv.tv_sec) { + ngx_cached_time = tv.tv_sec; + ngx_time_update(); + } if (timer != INFINITE) { - delta = ngx_msec() - delta; - ngx_event_expire_timers(delta); + delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; + ngx_event_expire_timers((ngx_msec_t) delta); } if (err) { 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 @@ -311,12 +311,13 @@ static int ngx_kqueue_set_event(ngx_even static int ngx_kqueue_process_events(ngx_log_t *log) { - int events, instance, i; - ngx_err_t err; - ngx_msec_t timer, delta; - ngx_event_t *ev; - struct timeval tv; - struct timespec ts, *tp; + int events, instance, i; + ngx_err_t err; + ngx_msec_t timer; + ngx_event_t *ev; + ngx_epoch_msec_t delta; + struct timeval tv; + struct timespec ts, *tp; timer = ngx_event_find_timer(); @@ -324,11 +325,11 @@ static int ngx_kqueue_process_events(ngx ts.tv_sec = timer / 1000; ts.tv_nsec = (timer % 1000) * 1000000; tp = &ts; - gettimeofday(&tv, NULL); + + ngx_gettimeofday(&tv); delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; } else { - timer = 0; delta = 0; tp = NULL; } @@ -347,7 +348,7 @@ static int ngx_kqueue_process_events(ngx nchanges = 0; - gettimeofday(&tv, NULL); + ngx_gettimeofday(&tv); if (ngx_cached_time != tv.tv_sec) { ngx_cached_time = tv.tv_sec; @@ -358,7 +359,7 @@ static int ngx_kqueue_process_events(ngx delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; #if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta); + ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ (int) delta); #endif /* @@ -366,7 +367,7 @@ static int ngx_kqueue_process_events(ngx * because the new timers can be added during a processing */ - ngx_event_expire_timers(delta); + ngx_event_expire_timers((ngx_msec_t) delta); } else { if (events == 0) { @@ -376,7 +377,7 @@ static int ngx_kqueue_process_events(ngx } #if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta); + ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ (int) delta); #endif } 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 @@ -224,16 +224,19 @@ static int ngx_poll_process_events(ngx_l { int ready, found, j; u_int nready, i; - ngx_msec_t timer, delta; + ngx_msec_t timer; ngx_err_t err; ngx_cycle_t **cycle; ngx_event_t *ev; + ngx_epoch_msec_t delta; ngx_connection_t *c; + struct timeval tv; timer = ngx_event_find_timer(); if (timer) { - delta = ngx_msec(); + ngx_gettimeofday(&tv); + delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; } else { timer = INFTIM; @@ -259,15 +262,20 @@ static int ngx_poll_process_events(ngx_l ngx_log_debug(log, "poll ready %d" _ ready); - /* TODO: time */ + ngx_gettimeofday(&tv); + + if (ngx_cached_time != tv.tv_sec) { + ngx_cached_time = tv.tv_sec; + ngx_time_update(); + } if ((int) timer != INFTIM) { - delta = ngx_msec() - delta; + delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; #if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ delta); + ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ (int) delta); #endif - ngx_event_expire_timers(delta); + ngx_event_expire_timers((ngx_msec_t) delta); } else { if (ready == 0) { @@ -277,7 +285,7 @@ static int ngx_poll_process_events(ngx_l } #if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ delta); + ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ (int) delta); #endif } 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 @@ -148,6 +148,7 @@ static int ngx_select_add_event(ngx_even } #if (WIN32) + if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE) || (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE)) { @@ -165,7 +166,9 @@ static int ngx_select_add_event(ngx_even FD_SET(c->fd, &master_write_fd_set); max_write++; } + #else + if (event == NGX_READ_EVENT) { FD_SET(c->fd, &master_read_fd_set); @@ -247,10 +250,14 @@ static int ngx_select_process_events(ngx int ready, found; u_int i, nready; ngx_err_t err; - ngx_msec_t timer, delta; + ngx_msec_t timer; ngx_event_t *ev; ngx_connection_t *c; + ngx_epoch_msec_t delta; struct timeval tv, *tp; +#if (HAVE_SELECT_CHANGE_TIMEOUT) + static ngx_epoch_msec_t deltas = 0; +#endif work_read_fd_set = master_read_fd_set; work_write_fd_set = master_write_fd_set; @@ -264,7 +271,8 @@ static int ngx_select_process_events(ngx #if (HAVE_SELECT_CHANGE_TIMEOUT) delta = 0; #else - delta = ngx_msec(); + ngx_gettimeofday(&tv); + delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; #endif } else { @@ -314,32 +322,69 @@ static int ngx_select_process_events(ngx ngx_log_debug(log, "select ready %d" _ ready); #endif - /* TODO: time */ +#if (HAVE_SELECT_CHANGE_TIMEOUT) if (timer) { -#if (HAVE_SELECT_CHANGE_TIMEOUT) delta = timer - (tv.tv_sec * 1000 + tv.tv_usec / 1000); -#if 0 /* - * update the cached time if the sum of the last deltas - * is more than 0.5 seconds + * learn the real time and update the cached time + * if the sum of the last deltas overcomes 1 second */ + deltas += delta; - if (deltas > 500000) { - ngx_cached_time = ngx_real_time(); - deltas = 0; + if (deltas > 1000) { + ngx_gettimeofday(&tv); + deltas = tv.tv_usec / 1000; + + if (ngx_cached_time != tv.tv_sec) { + ngx_cached_time = tv.tv_sec; + ngx_time_update(); + } } + +#if (NGX_DEBUG_EVENT) + ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ (int) delta); #endif -#else - delta = ngx_msec() - delta; + ngx_event_expire_timers((ngx_msec_t) delta); + + } else { + ngx_gettimeofday(&tv); + + if (ngx_cached_time != tv.tv_sec) { + ngx_cached_time = tv.tv_sec; + ngx_time_update(); + } + + if (ready == 0) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "select() returned no events without timeout"); + return NGX_ERROR; + } + +#if (NGX_DEBUG_EVENT) + ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ (int) delta); +#endif + } + +#else /* HAVE_SELECT_CHANGE_TIMEOUT */ + + ngx_gettimeofday(&tv); + + if (ngx_cached_time != tv.tv_sec) { + ngx_cached_time = tv.tv_sec; + ngx_time_update(); + } + + if (timer) { + delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; + +#if (NGX_DEBUG_EVENT) + ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ (int) delta); #endif -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ delta); -#endif - ngx_event_expire_timers(delta); + ngx_event_expire_timers((ngx_msec_t) delta); } else { if (ready == 0) { @@ -349,11 +394,12 @@ static int ngx_select_process_events(ngx } #if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ delta); + ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ (int) delta); #endif - ngx_event_expire_timers(delta); } +#endif /* HAVE_SELECT_CHANGE_TIMEOUT */ + if (err) { ngx_log_error(NGX_LOG_ALERT, log, err, "select() failed"); return NGX_ERROR; 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 @@ -429,7 +429,7 @@ int ngx_http_send_header(ngx_http_reques return NGX_OK; } - if (r->err_status) { + if (r->err_ctx) { r->headers_out.status = r->err_status; r->headers_out.status_line.len = 0; } @@ -499,17 +499,19 @@ int ngx_http_internal_redirect(ngx_http_ } } - /* clear the modules contexts */ + if (r->err_ctx) { - if (r->error_page) { - r->err_status = r->headers_out.status; - r->err_ctx = r->ctx; + /* allocate the new modules contexts */ + r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module); if (r->ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } } else { + + /* clear the modules contexts */ + ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module); } diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c --- a/src/http/ngx_http_parse_time.c +++ b/src/http/ngx_http_parse_time.c @@ -232,16 +232,22 @@ time_t ngx_http_parse_time(char *value, return NGX_ERROR; } - /* shift new year to 1st March, needed for Gauss's formula */ + /* shift new year to March 1, needed for Gauss's formula */ + if (--month <= 0) { month += 12; year -= 1; } - /* Gauss's formula for Grigorian days from 1 March 1 BC */ + + /* Gauss's formula for Grigorian days from 1 March 1 BC */ + return (365 * year + year / 4 - year / 100 + year / 400 + 367 * month / 12 + day - 31 - /* 719527 days are between 1 March 1 BC and 1 March 1970, - 31 and 28 days in Jan and Feb 1970 */ + /* + * 719527 days are between March 1, 1 BC and March 1, 1970, + * 31 and 28 days in January and February 1970 + */ + - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec; } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -205,8 +205,6 @@ struct ngx_http_request_s { unsigned bypass_cache:1; unsigned no_cache:1; - unsigned error_page:1; - #if 0 unsigned cachable:1; #endif 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 @@ -203,11 +203,12 @@ int ngx_http_special_response_handler(ng clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (!r->error_page && clcf->error_pages) { + if (r->err_ctx == NULL && clcf->error_pages) { err_page = clcf->error_pages->elts; for (i = 0; i < clcf->error_pages->nelts; i++) { if (err_page[i].code == error) { - r->error_page = 1; + 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_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 @@ -35,6 +35,7 @@ #define SIZE_FMT "%d" #define SIZEX_FMT "%x" #define PID_FMT "%d" +#define TIME_FMT "%lu" 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 @@ -33,6 +33,7 @@ typedef uint32_t u_int32_t; #define SIZE_FMT "%d" #define SIZEX_FMT "%x" #define PID_FMT "%ld" +#define TIME_FMT "%lu" #ifndef HAVE_SELECT 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 @@ -5,20 +5,22 @@ void ngx_localtime(ngx_tm_t *tm) { +#if (HAVE_LOCALTIME_R) + localtime_r(&ngx_cached_time, tm); +#else + ngx_tm_t *t; + + t = localtime(&ngx_cached_time); + *tm = *t; + +#endif + tm->ngx_tm_mon++; tm->ngx_tm_year += 1900; } -u_int ngx_msec(void) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - - return tv.tv_sec * 1000 + tv.tv_usec / 1000; -} #if 0 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 @@ -3,9 +3,13 @@ #include +#include + + +typedef uint64_t ngx_epoch_msec_t; typedef u_int ngx_msec_t; -#define NGX_MAX_MSEC (u_int) -1 +#define NGX_MAX_MSEC (ngx_msec_t) -1 typedef struct tm ngx_tm_t; @@ -17,16 +21,14 @@ typedef struct tm ngx_tm_t; #define ngx_tm_year tm_year #define ngx_tm_wday tm_wday -#define ngx_msleep(ms) usleep(ms * 1000) void ngx_localtime(ngx_tm_t *tm); -ngx_msec_t ngx_msec(void); +#define ngx_gettimeofday(tp) gettimeofday(tp, NULL); +#define ngx_msleep(ms) usleep(ms * 1000) -time_t ngx_time(); extern time_t ngx_cached_time; - #endif /* _NGX_TIME_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h --- a/src/os/win32/ngx_files.h +++ b/src/os/win32/ngx_files.h @@ -69,8 +69,8 @@ int ngx_file_type(char *filename, ngx_fi #define ngx_file_uniq(fi) (*(ngx_file_uniq_t *) &fi.nFileIndexHigh) -/* There are 134774 days between 1 Jan 1970 and 1 Jan 1601, - 11644473600 seconds or 11644473600,000,000,0 100-nanosecond intervals */ + +/* 116444736000000000 is commented in src/os/win32/ngx_time.c */ #define ngx_file_mtime(fi) \ (time_t) (((((unsigned __int64) fi.ftLastWriteTime.dwHighDateTime << 32) \ diff --git a/src/os/win32/ngx_time.c b/src/os/win32/ngx_time.c new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_time.c @@ -0,0 +1,29 @@ + +#include +#include + + +void ngx_gettimeofday(struct timeval *tp) +{ + uint64_t intervals; + FILETIME ft; + + GetSystemTimeAsFileTime(&ft); + + /* + * A file time is a 64-bit value that represents the number + * of 100-nanosecond intervals that have elapsed since + * 12:00 A.M. January 1, 1601 (UTC). + * + * Between January 1, 1970 (Epoch) and January 1, 1601 there are + * 134744 days, + * 11644473600 seconds or + * 11644473600,000,000,0 100-nanosecond intervals. + */ + + intervals = ((uint64_t) ft.dwHighDateTime << 32) | ft.dwLowDateTime; + intervals -= 116444736000000000; + + tp->tv_sec = intervals / 10000000; + tp->tv_usec = (intervals % 10000000) / 10; +} 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 @@ -6,8 +6,10 @@ #include -typedef unsigned int ngx_msec_t; -#define NGX_MAX_MSEC ~0 +typedef uint64_t ngx_epoch_msec_t; + +typedef u_int ngx_msec_t; +#define NGX_MAX_MSEC (ngx_msec_t) -1 typedef SYSTEMTIME ngx_tm_t; @@ -23,10 +25,16 @@ typedef FILETIME ngx_mtime_t; #define ngx_msleep Sleep #define ngx_localtime GetLocalTime -#define ngx_msec GetTickCount + -/* STUB */ -#define ngx_time() time(NULL) +struct timeval { + long tv_sec; + long tv_usec; +}; + + +void ngx_gettimeofday(struct timeval *tp); + #endif /* _NGX_TIME_H_INCLUDED_ */