diff options
-rw-r--r-- | auto/os/linux | 25 | ||||
-rw-r--r-- | src/core/ngx_radix_tree.c | 8 | ||||
-rw-r--r-- | src/event/modules/ngx_rtsig_module.c | 191 | ||||
-rw-r--r-- | src/event/ngx_event.c | 11 | ||||
-rw-r--r-- | src/event/ngx_event_busy_lock.c | 17 |
5 files changed, 188 insertions, 64 deletions
diff --git a/auto/os/linux b/auto/os/linux index 4a9823dd9..6fcd7647b 100644 --- a/auto/os/linux +++ b/auto/os/linux @@ -9,6 +9,22 @@ PIPE="-pipe" CC_TEST_FLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" +# Linux kernel version + +version=`grep "#define LINUX_VERSION_CODE" /usr/include/linux/version.h \ + | sed -e 's/^.* \(.*\)$/\1/'` + + +# enable rt signals on Linux 2.4.x + +if [ $version -ge 132096 -o $EVENT_RTSIG = YES ]; then + echo " + using rt signals" + have=HAVE_RTSIG . auto/have + EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE" + CORE_SRCS="$CORE_SRCS $RTSIG_SRCS" + EVENT_FOUND=YES +fi + # epoll, EPOLLET version @@ -30,15 +46,6 @@ if [ $ngx_found = yes ]; then fi -# rtsig - -if [ $EVENT_RTSIG = YES ]; then - have=HAVE_RTSIG . auto/have - EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE" - CORE_SRCS="$CORE_SRCS $RTSIG_SRCS" -fi - - # sendfile() CC_TEST_FLAGS="-D_GNU_SOURCE" diff --git a/src/core/ngx_radix_tree.c b/src/core/ngx_radix_tree.c index b63be1fa0..5c7a801d8 100644 --- a/src/core/ngx_radix_tree.c +++ b/src/core/ngx_radix_tree.c @@ -3,10 +3,6 @@ #include <ngx_core.h> -/* STUB: page size */ -#define NGX_RADIX_TREE_POOL_SIZE 4096 - - static void *ngx_radix_alloc(ngx_radix_tree_t *tree, size_t size); @@ -187,11 +183,11 @@ static void *ngx_radix_alloc(ngx_radix_tree_t *tree, size_t size) } if (tree->size < size) { - if (!(tree->start = ngx_palloc(tree->pool, NGX_RADIX_TREE_POOL_SIZE))) { + if (!(tree->start = ngx_palloc(tree->pool, ngx_pagesize))) { return NULL; } - tree->size = NGX_RADIX_TREE_POOL_SIZE; + tree->size = ngx_pagesize; } p = tree->start; diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c index 98a9155eb..5d957ecff 100644 --- a/src/event/modules/ngx_rtsig_module.c +++ b/src/event/modules/ngx_rtsig_module.c @@ -27,7 +27,10 @@ int sigtimedwait(const sigset_t *set, siginfo_t *info, typedef struct { - int signo; + int signo; + ngx_int_t overflow_events; + ngx_int_t overflow_test; + ngx_int_t overflow_threshold; } ngx_rtsig_conf_t; @@ -44,12 +47,18 @@ static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle); static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf); -static sigset_t set; -static ngx_uint_t overflow, current; +static sigset_t set; +static ngx_uint_t overflow, overflow_current; +static struct pollfd *overflow_list; static ngx_str_t rtsig_name = ngx_string("rtsig"); +static ngx_conf_num_bounds_t ngx_overflow_threshold_bounds = { + ngx_conf_check_num_bounds, 2, 10 +}; + + static ngx_command_t ngx_rtsig_commands[] = { {ngx_string("rtsig_signo"), @@ -59,6 +68,27 @@ static ngx_command_t ngx_rtsig_commands[] = { offsetof(ngx_rtsig_conf_t, signo), NULL}, + {ngx_string("rtsig_overflow_events"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_rtsig_conf_t, overflow_events), + NULL}, + + {ngx_string("rtsig_overflow_test"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_rtsig_conf_t, overflow_test), + NULL}, + + {ngx_string("rtsig_overflow_threshold"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_rtsig_conf_t, overflow_threshold), + &ngx_overflow_threshold_bounds}, + ngx_null_command }; @@ -113,6 +143,16 @@ static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle) return NGX_ERROR; } + if (overflow_list) { + ngx_free(overflow_list); + } + + overflow_list = ngx_alloc(sizeof(struct pollfd) * rtscf->overflow_events, + cycle->log); + if (overflow_list == NULL) { + return NGX_ERROR; + } + ngx_io = ngx_os_io; ngx_event_actions = ngx_rtsig_module_ctx.actions; @@ -339,7 +379,7 @@ ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle) if (signo == rtscf->signo || signo == rtscf->signo + 1) { - if (overflow && (ngx_uint_t) si.si_fd > current) { + if (overflow && (ngx_uint_t) si.si_fd > overflow_current) { return NGX_OK; } @@ -441,7 +481,7 @@ ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle) } overflow = 1; - current = 0; + overflow_current = 0; ngx_event_actions.process = ngx_rtsig_process_overflow; return NGX_OK; @@ -473,61 +513,123 @@ ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle) } +/* TODO: old cylces */ + static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle) { - int name[2], len, rtsig_max, rtsig_nr; - ngx_uint_t i, n; + int name[2], len, rtsig_max, rtsig_nr, events, ready; + ngx_int_t tested, n, i; + ngx_err_t err; ngx_connection_t *c; + ngx_rtsig_conf_t *rtscf; + + rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); - /* TODO: old cylces */ + tested = 0; - n = 0; - c = cycle->connections; - for (current = 0; current < cycle->connection_n; current++) { + for ( ;; ) { - i = current; + n = 0; + while (n < rtscf->overflow_events) { - if (c[i].fd == -1) { - continue; - } + if (overflow_current == cycle->connection_n) { + break; + } + + c = &cycle->connections[overflow_current++]; + + if (c->fd == -1) { + continue; + } + + events = 0; + + if (c->read->active && c->read->event_handler) { + events |= POLLIN; + } + + if (c->write->active && c->write->event_handler) { + events |= POLLOUT; + } + + if (events == 0) { + continue; + } - if (c[i].read->active && c[i].read->event_handler) { + overflow_list[n].fd = c->fd; + overflow_list[n].events = events; + overflow_list[n].revents = 0; n++; - c[i].read->ready = 1; + } - if (!ngx_threaded) { - c[i].read->event_handler(c[i].read); + if (n == 0) { + break; + } - } else { - if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { - return NGX_ERROR; - } + for ( ;; ) { + ready = poll(overflow_list, n, 0); - ngx_post_event(c[i].read); + if (ready == -1) { + err = ngx_errno; + ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, + cycle->log, 0, + "poll() failed while the overflow recover"); - ngx_mutex_unlock(ngx_posted_events_mutex); + if (err == NGX_EINTR) { + continue; + } } + + break; } - if (c[i].write->active && c[i].write->event_handler) { - n++; - c[i].write->ready = 1; + if (ready <= 0) { + continue; + } + + for (i = 0; i < n; i++) { + c = &cycle->connections[overflow_list[i].fd]; + + if (overflow_list[i].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) { + tested++; + c->read->ready = 1; + + if (!ngx_threaded) { + c->read->event_handler(c->read); + + } else { + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + return NGX_ERROR; + } + + ngx_post_event(c->read); + c->read->returned_instance = c->read->instance; + + ngx_mutex_unlock(ngx_posted_events_mutex); + } + } + + if (overflow_list[i].revents & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { + tested++; + c->write->ready = 1; - if (!ngx_threaded) { - c[i].write->event_handler(c[i].write); + if (!ngx_threaded) { + c->write->event_handler(c->write); - } else { - if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { - return NGX_ERROR; - } + } else { + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + return NGX_ERROR; + } - ngx_post_event(c[i].write); + ngx_post_event(c->write); + c->write->returned_instance = c->write->instance; - ngx_mutex_unlock(ngx_posted_events_mutex); + ngx_mutex_unlock(ngx_posted_events_mutex); + } } } - if (n && (n % 100 == 0)) { + if (tested >= rtscf->overflow_test) { /* * Check the current rt queue length to prevent the new overflow. @@ -555,15 +657,17 @@ static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle) } /* - * drain rt signal queue if the /proc/sys/kernel/rtsig-nr - * is bigger than "/proc/sys/kernel/rtsig-max / 4" + * drain rt signal queue if the /proc/sys/kernel/rtsig-nr is bigger + * than "/proc/sys/kernel/rtsig-max / rtsig_overflow_threshold" */ - if (rtsig_max / 4 < rtsig_nr) { + if (rtsig_max / rtscf->overflow_threshold < rtsig_nr) { ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "rtsig queue state: %d/%d", rtsig_nr, rtsig_max); while (ngx_rtsig_process_events(cycle) == NGX_OK) { /* void */ } } + + tested = 0; } } @@ -589,6 +693,9 @@ static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle) NGX_CONF_ERROR); rtscf->signo = NGX_CONF_UNSET; + rtscf->overflow_events = NGX_CONF_UNSET; + rtscf->overflow_test = NGX_CONF_UNSET; + rtscf->overflow_threshold = NGX_CONF_UNSET; return rtscf; } @@ -601,5 +708,9 @@ static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf) /* LinuxThreads use the first 3 RT signals */ ngx_conf_init_value(rtscf->signo, SIGRTMIN + 10); + ngx_conf_init_value(rtscf->overflow_events, 16); + ngx_conf_init_value(rtscf->overflow_test, 100); + ngx_conf_init_value(rtscf->overflow_threshold, 4); + return NGX_CONF_OK; } diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index b8bed8950..b4211be94 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -24,6 +24,11 @@ extern ngx_module_t ngx_epoll_module; extern ngx_event_module_t ngx_epoll_module_ctx; #endif +#if (HAVE_RTSIG) +extern ngx_module_t ngx_rtsig_module; +extern ngx_event_module_t ngx_rtsig_module_ctx; +#endif + #if (HAVE_AIO) #include <ngx_aio_module.h> #endif @@ -643,6 +648,12 @@ static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf) 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_RTSIG) + + ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS); + ngx_conf_init_value(ecf->use, ngx_rtsig_module.ctx_index); + ngx_conf_init_ptr_value(ecf->name, ngx_rtsig_module_ctx.name->data); + #elif (HAVE_SELECT) ngx_conf_init_unsigned_value(ecf->connections, diff --git a/src/event/ngx_event_busy_lock.c b/src/event/ngx_event_busy_lock.c index 5a7357c5e..a4db7f94b 100644 --- a/src/event/ngx_event_busy_lock.c +++ b/src/event/ngx_event_busy_lock.c @@ -40,11 +40,13 @@ ngx_int_t ngx_event_busy_lock(ngx_event_busy_lock_t *bl, ngx_add_timer(ctx->event, ctx->timer); ctx->event->event_handler = ngx_event_busy_lock_handler; - if (bl->events == NULL) { - bl->events = ctx; - } else { + if (bl->events) { bl->last->next = ctx; + + } else { + bl->events = ctx; } + bl->last = ctx; rc = NGX_AGAIN; @@ -149,8 +151,7 @@ ngx_int_t ngx_event_busy_unlock(ngx_event_busy_lock_t *bl, return NGX_ERROR; } - ev->next = (ngx_event_t *) ngx_posted_events; - ngx_posted_events = ev; + ngx_post_event(ev); ngx_mutex_unlock(ngx_posted_events_mutex); } @@ -175,8 +176,7 @@ ngx_int_t ngx_event_busy_unlock(ngx_event_busy_lock_t *bl, return NGX_ERROR; } - ev->next = (ngx_event_t *) ngx_posted_events; - ngx_posted_events = ev; + ngx_post_event(ev); ngx_mutex_unlock(ngx_posted_events_mutex); } @@ -287,8 +287,7 @@ static void ngx_event_busy_lock_handler(ngx_event_t *ev) return; } - ev->next = (ngx_event_t *) ngx_posted_events; - ngx_posted_events = ev; + ngx_post_event(ev); ngx_mutex_unlock(ngx_posted_events_mutex); |