diff options
author | Igor Sysoev <igor@sysoev.ru> | 2004-04-15 00:34:05 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2004-04-15 00:34:05 +0400 |
commit | cccc5528945be46d6afb456e7aba751340af9089 (patch) | |
tree | b734bef5df932252d9f04ddaf39ef80c83b0b0f2 /src/event | |
parent | b3968b314f063c42f983ba70becfb9fae97651f0 (diff) |
nginx-0.0.3-2004-04-15-00:34:05 import
Diffstat (limited to 'src/event')
-rw-r--r-- | src/event/modules/ngx_devpoll_module.c | 112 | ||||
-rw-r--r-- | src/event/modules/ngx_epoll_module.c | 27 | ||||
-rw-r--r-- | src/event/modules/ngx_kqueue_module.c | 49 | ||||
-rw-r--r-- | src/event/modules/ngx_poll_module.c | 24 | ||||
-rw-r--r-- | src/event/modules/ngx_rtsig_module.c | 92 | ||||
-rw-r--r-- | src/event/modules/ngx_select_module.c | 33 | ||||
-rw-r--r-- | src/event/ngx_event_timer.c | 6 | ||||
-rw-r--r-- | src/event/ngx_event_timer.h | 3 |
8 files changed, 268 insertions, 78 deletions
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c index 41188ae53..6007c0d98 100644 --- 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_event_t *ev, int event, u_int flags) } 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_t *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_t *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; + + } else { + expire = 1; + } + + if (ngx_accept_mutex) { + if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { + return NGX_ERROR; + } - if (timer == 0) { - timer = (ngx_msec_t) INFTIM; + 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_t *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_t *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_t *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_t *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 ((event_list[i].events & (POLLOUT|POLLERR|POLLHUP)) - && c->write->active) - { - c->write->ready = 1; - c->write->event_handler(c->write); + 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); + + 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 index cad7ed9b7..f5bd6e5ba 100644 --- 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 *cycle) 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 == -1) { - timer = 0; - expire = 1; + if (timer != 0) { + break; + } - } else if (timer == 0) { - timer = (ngx_msec_t) -1; + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "epoll expired timer"); + + 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 *cycle) 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 index bf37bf5b4..33dd71296 100644 --- 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_events(ngx_cycle_t *cycle) 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_events(ngx_cycle_t *cycle) } 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_events(ngx_cycle_t *cycle) 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_events(ngx_cycle_t *cycle) 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 index ffe59d49f..968180dbb 100644 --- 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 *cycle) expire = 0; } else { - timer = ngx_event_find_timer(); + for ( ;; ) { + timer = ngx_event_find_timer(); - if (timer == -1) { - timer = 0; - expire = 1; + if (timer != 0) { + break; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "poll expired timer"); + + ngx_event_expire_timers(0); + } + + /* NGX_TIMER_INFINITE == INFTIM */ - } else if (timer == 0) { - timer = (ngx_msec_t) INFTIM; + if (timer == NGX_TIMER_INFINITE) { expire = 0; } else { @@ -308,7 +316,7 @@ int ngx_poll_process_events(ngx_cycle_t *cycle) } 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 *cycle) 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 index 19234610d..b55f84c47 100644 --- 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 *cycle) { int signo; ngx_int_t instance, i; + ngx_uint_t expire; size_t n; ngx_msec_t timer; ngx_err_t err; @@ -199,22 +200,50 @@ int ngx_rtsig_process_events(ngx_cycle_t *cycle) struct timeval tv; struct timespec ts, *tp; struct sigaction sa; - ngx_connection_t *c; ngx_epoch_msec_t delta; + ngx_connection_t *c; 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; + } - if (timer) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "rtsig expired timer"); + + ngx_event_expire_timers(0); + } + + 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; + } + } + + 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 *cycle) 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 *cycle) 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 *cycle) } 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 index 0f3848d4e..91563f275 100644 --- 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_cycle_t *cycle) 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_cycle_t *cycle) } 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_cycle_t *cycle) } #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_cycle_t *cycle) #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_cycle_t *cycle) 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 index ab97ee195..a3d4d808d 100644 --- 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 timer) 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 index e0311b61d..3ff0e7c10 100644 --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -7,7 +7,8 @@ #include <ngx_event.h> -#define NGX_TIMER_ERROR (ngx_msec_t) -1 +#define NGX_TIMER_INFINITE -1 +#define NGX_TIMER_ERROR -2 /* * 32 bit timer key value resolution |