diff --git a/auto/options b/auto/options index 3064a950d..5311af5a5 100644 --- a/auto/options +++ b/auto/options @@ -5,6 +5,7 @@ CC=gcc OBJS=objs TEST_BUILD_DEVPOLL=NO +TEST_BUILD_EPOLL=NO SELECT=YES POLL=YES @@ -54,6 +55,7 @@ do --with-zlib=*) ZLIB="$value" ;; --test-build-devpoll) TEST_BUILD_DEVPOLL=YES ;; + --test-build-epoll) TEST_BUILD_EPOLL=YES ;; *) echo "$0: error: invalid option \"$option\"" diff --git a/auto/os/conf b/auto/os/conf index f0d25b647..add6068a8 100644 --- a/auto/os/conf +++ b/auto/os/conf @@ -44,6 +44,13 @@ esac if [ $TEST_BUILD_DEVPOLL = YES ]; then + CFLAGS="$CFLAGS -D HAVE_DEVPOLL=1 -D TEST_BUILD_DEVPOLL=1" EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE" - EVENT_SRCS="$EVENT_SRCS $DEVPOLL_SRCS" + CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS" +fi + +if [ $TEST_BUILD_EPOLL = YES ]; then + CFLAGS="$CFLAGS -D HAVE_EPOLL=1 -D TEST_BUILD_EPOLL=1" + EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE" + CORE_SRCS="$CORE_SRCS $EPOLL_SRCS" fi diff --git a/auto/os/linux b/auto/os/linux index bf5092aba..8990e6d19 100644 --- a/auto/os/linux +++ b/auto/os/linux @@ -7,6 +7,15 @@ EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE $POLL_MODULE" ZLIB_LIB="-lz" +NGX_INC="sys/epoll.h"; . auto/inc + +if [ $NGX_FOUND=YES ]; then + CFLAGS="$CFLAGS -D HAVE_EPOLL=1" + EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE" + CORE_SRCS="$CORE_SRCS $EPOLL_SRCS" +fi + + # TODO check sendfile64() CC_TEST_FLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" diff --git a/auto/sources b/auto/sources index b352effbb..c83ffa724 100644 --- a/auto/sources +++ b/auto/sources @@ -74,6 +74,9 @@ KQUEUE_SRCS=src/event/modules/ngx_kqueue_module.c DEVPOLL_MODULE="ngx_devpoll_module" DEVPOLL_SRCS=src/event/modules/ngx_devpoll_module.c +EPOLL_MODULE="ngx_epoll_module" +EPOLL_SRCS=src/event/modules/ngx_epoll_module.c + IOCP_MODULE="ngx_iocp_module" IOCP_SRCS=src/event/modules/ngx_iocp_module.c diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c index 8a319c76f..9326d2bd5 100644 --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -37,9 +37,10 @@ void ngx_time_init() 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_time = 0; ngx_gettimeofday(&tv); - ngx_cached_time = 0; + ngx_start_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000; ngx_old_elapsed_msec = 0; ngx_elapsed_msec = 0; diff --git a/src/core/ngx_times.h b/src/core/ngx_times.h index 296004220..7823af0b8 100644 --- a/src/core/ngx_times.h +++ b/src/core/ngx_times.h @@ -15,13 +15,24 @@ void ngx_gmtime(time_t t, ngx_tm_t *tp); extern time_t ngx_cached_time; -extern ngx_epoch_msec_t ngx_elapsed_msec; -extern ngx_epoch_msec_t ngx_old_elapsed_msec; -extern ngx_epoch_msec_t ngx_start_msec; - 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 ngx_epoch_msec_t ngx_start_msec; + +/* + * msecs elapsed since ngx_start_msec in the current event cycle, + * used in ngx_event_add_timer() and ngx_event_find_timer() + */ +extern ngx_epoch_msec_t ngx_elapsed_msec; + +/* + * msecs elapsed since ngx_start_msec in the previous event cycle, + * used in ngx_event_expire_timers() + */ +extern ngx_epoch_msec_t ngx_old_elapsed_msec; + + #endif /* _NGX_TIMES_H_INCLUDED_ */ diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c index c8217de58..d1d8f1788 100644 --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -106,9 +106,6 @@ static int ngx_devpoll_init(ngx_cycle_t *cycle) dpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_devpoll_module); -ngx_log_debug(cycle->log, "CH: %d" _ dpcf->changes); -ngx_log_debug(cycle->log, "EV: %d" _ dpcf->events); - if (dp == -1) { dp = open("/dev/poll", O_RDWR); @@ -122,7 +119,7 @@ ngx_log_debug(cycle->log, "EV: %d" _ dpcf->events); if (max_changes < dpcf->changes) { if (nchanges) { n = nchanges * sizeof(struct pollfd); - if ((size_t) write(dp, change_list, n) != n) { + if (write(dp, change_list, n) != (ssize_t) n) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "write(/dev/poll) failed"); return NGX_ERROR; @@ -199,8 +196,8 @@ static void ngx_devpoll_done(ngx_cycle_t *cycle) static int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags) { -#if (NGX_DEBUG_EVENT) - ngx_connection_t *c = (ngx_connection_t *) ev->data; +#if (NGX_DEBUG) + ngx_connection_t *c; #endif #if (NGX_READ_EVENT != POLLIN) @@ -213,9 +210,10 @@ static int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags) } #endif -#if (NGX_DEBUG_EVENT) - c = (ngx_connection_t *) ev->data; - ngx_log_debug(ev->log, "add event: %d:%d" _ c->fd _ event); +#if (NGX_DEBUG) + c = ev->data; + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "devpoll add event: fd:%d ev:%04X", c->fd, event); #endif ev->active = 1; @@ -230,9 +228,8 @@ static int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags) c = ev->data; -#if (NGX_DEBUG_EVENT) - ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event); -#endif + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "devpoll del event: fd:%d ev:%04X", c->fd, event); if (ngx_devpoll_set_event(ev, POLLREMOVE, flags) == NGX_ERROR) { return NGX_ERROR; @@ -270,17 +267,15 @@ static int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags) c = ev->data; -#if (NGX_DEBUG_EVENT) - ngx_log_debug(ev->log, "devpoll fd:%d event:%d flush:%d" _ - c->fd _ event _ flags); -#endif + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "devpoll fd:%d ev:%d fl:%d", c->fd, event, flags); if (nchanges >= max_changes) { ngx_log_error(NGX_LOG_WARN, ev->log, 0, "/dev/pool change list is filled up"); n = nchanges * sizeof(struct pollfd); - if ((size_t) write(dp, change_list, n) != n) { + if (write(dp, change_list, n) != (ssize_t) n) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "write(/dev/poll) failed"); return NGX_ERROR; @@ -300,7 +295,7 @@ static int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags) if (flags & NGX_CLOSE_EVENT) { n = nchanges * sizeof(struct pollfd); - if ((size_t) write(dp, change_list, n) != n) { + if (write(dp, change_list, n) != (ssize_t) n) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "write(/dev/poll) failed"); return NGX_ERROR; @@ -320,29 +315,23 @@ int ngx_devpoll_process_events(ngx_log_t *log) ngx_msec_t timer; ngx_err_t err; ngx_cycle_t **cycle; - ngx_epoch_msec_t delta; ngx_connection_t *c; + ngx_epoch_msec_t delta; struct dvpoll dvp; struct timeval tv; timer = ngx_event_find_timer(); + ngx_old_elapsed_msec = ngx_elapsed_msec; - if (timer) { - ngx_gettimeofday(&tv); - delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; - - } else { + if (timer == 0) { timer = (ngx_msec_t) INFTIM; - delta = 0; } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "devpoll timer: %d" _ timer); -#endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "devpoll timer: %d", timer); if (nchanges) { n = nchanges * sizeof(struct pollfd); - if ((size_t) write(dp, change_list, n) != n) { + if (write(dp, change_list, n) != (ssize_t) n) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "write(/dev/poll) failed"); return NGX_ERROR; @@ -363,34 +352,27 @@ int ngx_devpoll_process_events(ngx_log_t *log) nchanges = 0; ngx_gettimeofday(&tv); + ngx_time_update(tv.tv_sec); - if (ngx_cached_time != tv.tv_sec) { - ngx_cached_time = tv.tv_sec; - ngx_time_update(); - } + delta = ngx_elapsed_msec; + ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; if ((int) timer != INFTIM) { - delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; - -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ (int)delta); -#endif - ngx_event_expire_timers((ngx_msec_t) delta); + delta = ngx_elapsed_msec - delta; + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "devpoll timer: %d, delta: %d", timer, (int) delta); } else { if (events == 0) { ngx_log_error(NGX_LOG_ALERT, log, 0, "ioctl(DP_POLL) returned no events without timeout"); return NGX_ERROR; } - -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "devpoll timer: %d, delta: %d" _ timer _ (int)delta); -#endif } if (err) { - ngx_log_error(NGX_LOG_ALERT, log, err, "ioctl(DP_POLL) failed"); + ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, + log, err, "ioctl(DP_POLL) failed"); return NGX_ERROR; } @@ -411,15 +393,14 @@ int ngx_devpoll_process_events(ngx_log_t *log) } if (c->fd == -1) { - ngx_log_error(NGX_LOG_ALERT, log, 0, "unkonwn cycle"); + ngx_log_error(NGX_LOG_EMERG, log, 0, "unknown cycle"); exit(1); } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "devpoll: %d: ev:%d rev:%d" _ - event_list[i].fd _ - event_list[i].events _ event_list[i].revents); -#endif + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, + "devpoll: fd:%d, ev:%04X, rev:%04X", + event_list[i].fd, + event_list[i].events, event_list[i].revents); if (event_list[i].revents & POLLIN) { if (!c->read->active) { @@ -451,6 +432,10 @@ int ngx_devpoll_process_events(ngx_log_t *log) } } + if (timer != (ngx_msec_t) INFTIM && delta) { + ngx_event_expire_timers((ngx_msec_t) delta); + } + return NGX_OK; } diff --git a/src/event/modules/ngx_devpoll_module.h b/src/event/modules/ngx_devpoll_module.h deleted file mode 100644 index bd906fd49..000000000 --- a/src/event/modules/ngx_devpoll_module.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _NGX_DEVPOLL_MODULE_H_INCLUDED_ -#define _NGX_DEVPOLL_MODULE_H_INCLUDED_ - - -#include -#include -#include - -int ngx_devpoll_init(int max_connections, ngx_log_t *log); -int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags); -int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags); -void ngx_devpoll_add_timer(ngx_event_t *ev, ngx_msec_t timer); -int ngx_devpoll_process_events(ngx_log_t *log); - - -#if 0 -/* Solaris */ - -#define POLLREMOVE 0x0800 - -#define DP_POLL 0xD001 - -struct dvpoll { - struct pollfd *dp_fds; - int dp_nfds; - int dp_timeout; -}; - -#endif - - -#endif /* _NGX_DEVPOLL_MODULE_H_INCLUDED_ */ diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c new file mode 100644 index 000000000..e8d4a7278 --- /dev/null +++ b/src/event/modules/ngx_epoll_module.c @@ -0,0 +1,344 @@ + +/* + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ + */ + + +#include +#include +#include + + +#if (TEST_BUILD_EPOLL) + +/* epoll declarations */ + +#define EPOLLIN 0x001 +#define EPOLLPRI 0x002 +#define EPOLLOUT 0x004 +#define EPOLLRDNORM 0x040 +#define EPOLLRDBAND 0x080 +#define EPOLLWRNORM 0x100 +#define EPOLLWRBAND 0x200 +#define EPOLLMSG 0x400 +#define EPOLLERR 0x008 +#define EPOLLHUP 0x010 + +#define EPOLL_CTL_ADD 1 +#define EPOLL_CTL_DEL 2 +#define EPOLL_CTL_MOD 3 + +typedef union epoll_data { + void *ptr; + int fd; + uint32_t u32; + uint64_t u64; +} epoll_data_t; + +struct epoll_event { + uint32_t events; + epoll_data_t data; +}; + +int epoll_create(int size); +int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); +int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout); + +int epoll_create(int size) +{ + return -1; +} + +int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +{ + return -1; +} + +int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout) +{ + return -1; +} + +#endif + + +typedef struct { + u_int events; +} ngx_epoll_conf_t; + + +static int ngx_epoll_init(ngx_cycle_t *cycle); +static void ngx_epoll_done(ngx_cycle_t *cycle); +static int ngx_epoll_add_connection(ngx_connection_t *c); +static int ngx_epoll_del_connection(ngx_connection_t *c); +static int ngx_epoll_process_events(ngx_log_t *log); + +static void *ngx_epoll_create_conf(ngx_cycle_t *cycle); +static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf); + +static int ep = -1; +static struct epoll_event *event_list; +static u_int nevents; + + +static ngx_str_t epoll_name = ngx_string("epoll"); + +static ngx_command_t ngx_epoll_commands[] = { + + {ngx_string("epoll_events"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_epoll_conf_t, events), + NULL}, + + ngx_null_command +}; + + +ngx_event_module_t ngx_epoll_module_ctx = { + &epoll_name, + ngx_epoll_create_conf, /* create configuration */ + ngx_epoll_init_conf, /* init configuration */ + + { + NULL, /* add an event */ + NULL, /* delete an event */ + NULL, /* enable an event */ + NULL, /* disable an event */ + ngx_epoll_add_connection, /* add an connection */ + ngx_epoll_del_connection, /* delete an connection */ + ngx_epoll_process_events, /* process the events */ + ngx_epoll_init, /* init the events */ + ngx_epoll_done, /* done the events */ + } + +}; + +ngx_module_t ngx_epoll_module = { + NGX_MODULE, + &ngx_epoll_module_ctx, /* module context */ + ngx_epoll_commands, /* module directives */ + NGX_EVENT_MODULE, /* module type */ + NULL, /* init module */ + NULL /* init child */ +}; + + +static int ngx_epoll_init(ngx_cycle_t *cycle) +{ + size_t n; + ngx_epoll_conf_t *epcf; + + epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module); + + if (ep == -1) { + ep = epoll_create(/* STUB: open_files / 2 */ 512); + + if (ep == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "epoll_create() failed"); + return NGX_ERROR; + } + } + + if (nevents < epcf->events) { + if (event_list) { + ngx_free(event_list); + } + + event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events, + cycle->log); + if (event_list == NULL) { + return NGX_ERROR; + } + } + + nevents = epcf->events; + + ngx_io = ngx_os_io; + + ngx_event_actions = ngx_epoll_module_ctx.actions; + + ngx_event_flags = NGX_USE_EDGE_EVENT; + + return NGX_OK; +} + + +static void ngx_epoll_done(ngx_cycle_t *cycle) +{ + if (close(ep) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "epoll close() failed"); + } + + ep = -1; + + ngx_free(event_list); + + event_list = NULL; + nevents = 0; +} + + +static int ngx_epoll_add_connection(ngx_connection_t *c) +{ + struct epoll_event ev; + + ev.events = EPOLLIN|EPOLLOUT; + ev.data.ptr = (void *) ((uintptr_t) c | c->read->instance); + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, + "epoll add connection: fd:%d ev:%04X", c->fd, ev.events); + + if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ev) == -1) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + "epoll_ctl(#%d) failed", c->fd); + return NGX_ERROR; + } + + return NGX_OK; +} + + +static int ngx_epoll_del_connection(ngx_connection_t *c) +{ + c->read->active = 0; + c->write->active = 0; + + return NGX_OK; +} + + +int ngx_epoll_process_events(ngx_log_t *log) +{ + int events; + ngx_int_t instance, i; + size_t n; + ngx_msec_t timer; + ngx_err_t err; + ngx_cycle_t **cycle; + struct timeval tv; + ngx_connection_t *c; + ngx_epoch_msec_t delta; + + + timer = ngx_event_find_timer(); + ngx_old_elapsed_msec = ngx_elapsed_msec; + + if (timer == 0) { + timer = (ngx_msec_t) -1; + } + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "epoll timer: %d", timer); + + events = epoll_wait(ep, event_list, nevents, timer); + + if (events == -1) { + err = ngx_errno; + } else { + err = 0; + } + + ngx_gettimeofday(&tv); + ngx_time_update(tv.tv_sec); + + delta = ngx_elapsed_msec; + ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; + + if ((int) timer != INFTIM) { + delta = ngx_elapsed_msec - delta; + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "epoll timer: %d, delta: %d", timer, (int) delta); + } else { + if (events == 0) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "epoll_wait() returned no events without timeout"); + return NGX_ERROR; + } + } + + if (err) { + ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, + log, err, "epoll_wait() failed"); + return NGX_ERROR; + } + + for (i = 0; i < events; i++) { + c = event_list[i].data.ptr; + + instance = (uintptr_t) c & 1; + c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1); + + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, + "epoll: fd:%d ev:%04X d:" PTR_FMT, + c->fd, event_list[i].events, event_list[i].data); + + if (c->read->instance != instance) { + + /* + * it's a stale event from a file descriptor + * that was just closed in this iteration + */ + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, + "epoll: stale event " PTR_FMT, c); + continue; + } + + if (event_list[i].events & EPOLLIN) { + if (!c->read->active) { + continue; + } + + c->read->ready = 1; + c->read->event_handler(c->read); + } + + if (event_list[i].events & EPOLLOUT) { + if (!c->write->active) { + continue; + } + + c->write->ready = 1; + c->write->event_handler(c->write); + } + + if (event_list[i].events & (EPOLLERR|EPOLLHUP|EPOLLMSG)) { + ngx_log_error(NGX_LOG_ERR, log, 0, + "epoll_wait() error on fd:%d ev:%d", + c->fd, event_list[i].events); + } + } + + if (timer != (ngx_msec_t) -1 && delta) { + ngx_event_expire_timers((ngx_msec_t) delta); + } + + return NGX_OK; +} + + +static void *ngx_epoll_create_conf(ngx_cycle_t *cycle) +{ + ngx_epoll_conf_t *epcf; + + ngx_test_null(epcf, ngx_palloc(cycle->pool, sizeof(ngx_epoll_conf_t)), + NGX_CONF_ERROR); + + epcf->events = NGX_CONF_UNSET; + + return epcf; +} + + +static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf) +{ + ngx_epoll_conf_t *epcf = conf; + + ngx_conf_init_unsigned_value(epcf->events, 512); + + return NGX_CONF_OK; +} diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index b261e1be6..7e1cfa295 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -339,7 +339,8 @@ 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) { - ngx_int_t events, instance, i; + int events; + ngx_int_t instance, i; ngx_err_t err; ngx_msec_t timer; ngx_event_t *ev; @@ -355,13 +356,7 @@ static int ngx_kqueue_process_events(ngx_log_t *log) ts.tv_nsec = (timer % 1000) * 1000000; tp = &ts; -#if 0 - ngx_gettimeofday(&tv); - delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; -#endif - } else { - delta = 0; tp = NULL; } @@ -378,17 +373,17 @@ static int ngx_kqueue_process_events(ngx_log_t *log) nchanges = 0; ngx_gettimeofday(&tv); - -#if 1 - delta = ngx_elapsed_msec; -#endif - ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; - ngx_time_update(tv.tv_sec); + delta = ngx_elapsed_msec; + ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; + if (timer) { delta = ngx_elapsed_msec - delta; + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "kevent timer: %d, delta: %d", timer, (int) delta); + } else { if (events == 0) { ngx_log_error(NGX_LOG_ALERT, log, 0, @@ -397,9 +392,6 @@ static int ngx_kqueue_process_events(ngx_log_t *log) } } - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, - "kevent timer: %d, delta: %d", timer, (int) delta); - if (err) { ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, log, err, "kevent() failed"); @@ -496,33 +488,6 @@ static int ngx_kqueue_process_events(ngx_log_t *log) } -#if 0 - -static void ngx_kqueue_thread_handler(ngx_event_t *ev, ngx_log_t *log) -{ - ngx_int_t instance; - - instance = (uintptr_t) ev & 1; - ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1); - - if (ev->active && ev->instance == instance) { - ev->event_handler(ev); - return; - } - - /* - * it's a stale event from a file descriptor - * that was just closed in this iteration - */ - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, - "kevent: stale event " PTR_FMT, ev); - -} - -#endif - - static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle) { ngx_kqueue_conf_t *kcf; diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c index 7b69de50b..5f12eb11e 100644 --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru + * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ */ @@ -146,9 +146,8 @@ static int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) #endif } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(ev->log, "add event: %d:%d" _ c->fd _ event); -#endif + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "poll add event: fd:%d ev:%d", c->fd, event); if (e == NULL || e->index == NGX_INVALID_INDEX) { event_list[nevents].fd = c->fd; @@ -192,9 +191,8 @@ static int ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags) #endif } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event); -#endif + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "poll del event: fd:%d ev:%d", c->fd, event); if (e == NULL || e->index == NGX_INVALID_INDEX) { if (ev->index < (u_int) --nevents) { @@ -221,28 +219,24 @@ static int ngx_poll_process_events(ngx_log_t *log) ngx_err_t err; ngx_cycle_t **cycle; ngx_event_t *ev; - ngx_epoch_msec_t delta; + ngx_epoch_msec_t delta; ngx_connection_t *c; - struct timeval tv; + struct timeval tv; timer = ngx_event_find_timer(); + ngx_old_elapsed_msec = ngx_elapsed_msec; - if (timer) { - ngx_gettimeofday(&tv); - delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; - - } else { + if (timer == 0) { timer = (ngx_msec_t) INFTIM; - delta = 0; } -#if (NGX_DEBUG_EVENT) +#if (NGX_DEBUG) for (i = 0; i < nevents; i++) { - ngx_log_debug(log, "poll: %d, %d" _ - event_list[i].fd _ event_list[i].events); + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, "poll: fd:%d ev:%04X", + event_list[i].fd, event_list[i].events); } - ngx_log_debug(log, "poll timer: %d" _ timer); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "poll timer: %d", timer); #endif ready = poll(event_list, (u_int) nevents, (int) timer); @@ -253,33 +247,30 @@ static int ngx_poll_process_events(ngx_log_t *log) err = 0; } - ngx_log_debug(log, "poll ready %d" _ ready); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "poll ready %d", ready); ngx_gettimeofday(&tv); ngx_time_update(tv.tv_sec); + delta = ngx_elapsed_msec; + ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; + if ((int) timer != INFTIM) { - delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; - -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ (int) delta); -#endif - ngx_event_expire_timers((ngx_msec_t) delta); + delta = ngx_elapsed_msec - delta; + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "poll timer: %d, delta: %d", timer, (int) delta); } else { if (ready == 0) { ngx_log_error(NGX_LOG_ALERT, log, 0, "poll() returned no events without timeout"); return NGX_ERROR; } - -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ (int) delta); -#endif } if (err) { - ngx_log_error(NGX_LOG_ALERT, log, err, "poll() failed"); + ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, + log, err, "poll() failed"); return NGX_ERROR; } @@ -306,11 +297,10 @@ static int ngx_poll_process_events(ngx_log_t *log) exit(1); } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "poll: fd:%d, ev:%d, rev:%d" _ - event_list[i].fd _ - event_list[i].events _ event_list[i].revents); -#endif + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, + "poll: fd:%d ev:%04X rev:%04X", + event_list[i].fd, + event_list[i].events, event_list[i].revents); found = 0; @@ -343,7 +333,7 @@ static int ngx_poll_process_events(ngx_log_t *log) if (event_list[i].revents & (POLLERR|POLLHUP)) { ngx_log_error(NGX_LOG_ALERT, log, 0, - "strange poll() error on %d:%d:%d", + "strange poll() error on fd:%d ev:%04X rev:%04X", event_list[i].fd, event_list[i].events, event_list[i].revents); } @@ -377,5 +367,9 @@ static int ngx_poll_process_events(ngx_log_t *log) ngx_log_error(NGX_LOG_ALERT, log, 0, "poll ready != events"); } + if (timer != (ngx_msec_t) INFTIM && delta) { + ngx_event_expire_timers((ngx_msec_t) delta); + } + return NGX_OK; } diff --git a/src/event/modules/ngx_poll_module.h b/src/event/modules/ngx_poll_module.h deleted file mode 100644 index b9fcec281..000000000 --- a/src/event/modules/ngx_poll_module.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _NGX_POLL_MODULE_H_INCLUDED_ -#define _NGX_POLL_MODULE_H_INCLUDED_ - - -#include -#include -#include - -int ngx_poll_init(int max_connections, ngx_log_t *log); -int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags); -int ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags); -void ngx_poll_add_timer(ngx_event_t *ev, ngx_msec_t timer); -int ngx_poll_process_events(ngx_log_t *log); - - -#endif /* _NGX_POLL_MODULE_H_INCLUDED_ */ diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c index 66783e7e4..18d1bde7c 100644 --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -131,9 +131,8 @@ static int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) c = ev->data; -#if (NGX_DEBUG_EVENT) - ngx_log_debug(ev->log, "select fd:%d event:%d" _ c->fd _ event); -#endif + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "select add event fd:%d ev:%d", c->fd, event); if (ev->index != NGX_INVALID_INDEX) { ngx_log_error(NGX_LOG_ALERT, ev->log, 0, @@ -197,9 +196,8 @@ static int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags) return NGX_OK; } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event); -#endif + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "select del event fd:%d ev:%d", c->fd, event); #if (WIN32) @@ -259,19 +257,11 @@ static int ngx_select_process_events(ngx_log_t *log) ngx_old_elapsed_msec = ngx_elapsed_msec; if (timer) { -#if (HAVE_SELECT_CHANGE_TIMEOUT) - delta = 0; -#else - ngx_gettimeofday(&tv); - delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; -#endif - tv.tv_sec = timer / 1000; tv.tv_usec = (timer % 1000) * 1000; tp = &tv; } else { - delta = 0; tp = NULL; } @@ -284,22 +274,22 @@ static int ngx_select_process_events(ngx_log_t *log) } } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "change max_fd: %d" _ max_fd); -#endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, + "change max_fd: %d", max_fd); } #endif -#if (NGX_DEBUG_EVENT) +#if (NGX_DEBUG) for (i = 0; i < nevents; i++) { ev = event_index[i]; c = (ngx_connection_t *) ev->data; - ngx_log_debug(log, "select: %d:%d" _ c->fd _ ev->write); + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "select event: fd:%d wr:%d", c->fd,ev->write); } - - ngx_log_debug(log, "select timer: %d" _ timer); #endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "select timer: %d", timer); + #if (WIN32) ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp); #else @@ -312,10 +302,6 @@ static int ngx_select_process_events(ngx_log_t *log) err = 0; } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "select ready %d" _ ready); -#endif - #if (HAVE_SELECT_CHANGE_TIMEOUT) if (timer) { @@ -330,51 +316,36 @@ static int ngx_select_process_events(ngx_log_t *log) 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(); - } + ngx_time_update(tv.tv_sec); } -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ (int) delta); -#endif - - ngx_event_expire_timers((ngx_msec_t) delta); + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "select timer: %d, delta: %d", timer, (int) delta); } else { ngx_gettimeofday(&tv); - - if (ngx_cached_time != tv.tv_sec) { - ngx_cached_time = tv.tv_sec; - ngx_time_update(); - } + ngx_time_update(tv.tv_sec); 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 */ +#else /* !(HAVE_SELECT_CHANGE_TIMEOUT) */ ngx_gettimeofday(&tv); ngx_time_update(tv.tv_sec); + delta = ngx_elapsed_msec; + ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; + if (timer) { - delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; + delta = ngx_elapsed_msec - delta; -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ (int) delta); -#endif - - ngx_event_expire_timers((ngx_msec_t) delta); + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "select timer: %d, delta: %d", timer, (int) delta); } else { if (ready == 0) { @@ -382,16 +353,15 @@ static int ngx_select_process_events(ngx_log_t *log) "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 } #endif /* HAVE_SELECT_CHANGE_TIMEOUT */ + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "select ready %d", ready); + if (err) { - ngx_log_error(NGX_LOG_ALERT, log, err, "select() failed"); + ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, + log, err, "select() failed"); return NGX_ERROR; } @@ -405,17 +375,15 @@ static int ngx_select_process_events(ngx_log_t *log) if (ev->write) { if (FD_ISSET(c->fd, &work_write_fd_set)) { found = 1; -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "select write %d" _ c->fd); -#endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, + "select write %d", c->fd); } } else { if (FD_ISSET(c->fd, &work_read_fd_set)) { found = 1; -#if (NGX_DEBUG_EVENT) - ngx_log_debug(log, "select read %d" _ c->fd); -#endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, + "select read %d", c->fd); } } @@ -453,6 +421,10 @@ static int ngx_select_process_events(ngx_log_t *log) ngx_log_error(NGX_LOG_ALERT, log, 0, "select ready != events"); } + if (timer && delta) { + ngx_event_expire_timers((ngx_msec_t) delta); + } + return NGX_OK; } diff --git a/src/event/modules/ngx_select_module.h b/src/event/modules/ngx_select_module.h deleted file mode 100644 index 143a2cb3c..000000000 --- a/src/event/modules/ngx_select_module.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _NGX_SELECT_MODULE_H_INCLUDED_ -#define _NGX_SELECT_MODULE_H_INCLUDED_ - - -#include -#include -#include - -int ngx_select_init(int max_connections, ngx_log_t *log); -int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags); -int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags); -void ngx_select_add_timer(ngx_event_t *ev, ngx_msec_t timer); -int ngx_select_process_events(ngx_log_t *log); - - -#endif /* _NGX_SELECT_MODULE_H_INCLUDED_ */ diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index fada46122..bf6634661 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -134,7 +134,8 @@ static int ngx_event_init(ngx_cycle_t *cycle) if (ngx_modules[m]->ctx_index == ecf->use) { module = ngx_modules[m]->ctx; if (module->actions.init(cycle) == NGX_ERROR) { - return NGX_ERROR; + /* fatal */ + exit(2); } break; } diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 1c1066263..75701cb83 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -192,6 +192,10 @@ void ngx_event_accept(ngx_event_t *ev) rev->ready = 1; } + if (ev->deferred_accept) { + rev->ready = 1; + } + c->ctx = ls->ctx; c->servers = ls->servers; @@ -215,10 +219,6 @@ void ngx_event_accept(ngx_event_t *ev) ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "accept: %d, %d", s, c->number); - if (ev->deferred_accept) { - rev->ready = 1; - } - if (ngx_add_conn) { if (ngx_add_conn(c) == NGX_ERROR) { if (ngx_close_socket(s) == -1) {