# HG changeset patch # User Igor Sysoev # Date 1089212460 0 # Node ID 02a511569afb683a42f9e0351c405c0145456fd5 # Parent 5ce6561246a5cf128a59e4ba72aed2192477ded0 nginx-0.0.7-2004-07-07-19:01:00 import diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -15,6 +15,10 @@ static ngx_event_t ngx_cleaner_event ngx_uint_t ngx_test_config; +#if (NGX_THREADS) +ngx_tls_key_t ngx_core_tls_key; +#endif + /* STUB NAME */ static ngx_connection_t dumb; diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -49,6 +49,11 @@ typedef struct { } ngx_core_conf_t; +typedef struct { + ngx_pool_t *pool; /* pcre's malloc() pool */ +} ngx_core_tls_t; + + ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle); ngx_int_t ngx_create_pidfile(ngx_cycle_t *cycle, ngx_cycle_t *old_cycle); void ngx_delete_pidfile(ngx_cycle_t *cycle); @@ -60,6 +65,9 @@ extern volatile ngx_cycle_t *ngx_cycle; extern ngx_array_t ngx_old_cycles; extern ngx_module_t ngx_core_module; extern ngx_uint_t ngx_test_config; +#if (NGX_THREADS) +extern ngx_tls_key_t ngx_core_tls_key; +#endif #endif /* _NGX_CYCLE_H_INCLUDED_ */ diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c --- a/src/core/ngx_regex.c +++ b/src/core/ngx_regex.c @@ -7,7 +7,6 @@ static void *ngx_regex_malloc(size_t siz static void ngx_regex_free(void *p); -/* THREADS: this pool should be private for each thread */ static ngx_pool_t *ngx_pcre_pool; @@ -21,12 +20,29 @@ void ngx_regex_init() ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool, ngx_str_t *err) { - int erroff; - const char *errstr; - ngx_regex_t *re; + int erroff; + const char *errstr; + ngx_regex_t *re; +#if (NGX_THREADS) + ngx_core_tls_t *tls; + +#if (NGX_SUPPRESS_WARN) + tls = NULL; +#endif + + if (ngx_threaded) { + tls = ngx_thread_get_tls(ngx_core_tls_key); + tls->pool = pool; + } else { + ngx_pcre_pool = pool; + } + +#else ngx_pcre_pool = pool; +#endif + re = pcre_compile((const char *) pattern->data, (int) options, &errstr, &erroff, NULL); @@ -44,7 +60,15 @@ ngx_regex_t *ngx_regex_compile(ngx_str_t /* ensure that there is no current pool */ +#if (NGX_THREADS) + if (ngx_threaded) { + tls->pool = NULL; + } else { + ngx_pcre_pool = NULL; + } +#else ngx_pcre_pool = NULL; +#endif return re; } @@ -68,8 +92,22 @@ ngx_int_t ngx_regex_exec(ngx_regex_t *re static void *ngx_regex_malloc(size_t size) { - if (ngx_pcre_pool) { - return ngx_palloc(ngx_pcre_pool, size); + ngx_pool_t *pool; +#if (NGX_THREADS) + ngx_core_tls_t *tls; + + if (ngx_threaded) { + tls = ngx_thread_get_tls(ngx_core_tls_key); + pool = tls->pool; + } else { + pool = ngx_pcre_pool; + } +#else + pool = ngx_pcre_pool; +#endif + + if (pool) { + return ngx_palloc(pool, size); } return NULL; 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,6 +322,7 @@ int ngx_devpoll_process_events(ngx_cycle ngx_msec_t timer; ngx_err_t err; ngx_cycle_t **old_cycle; + ngx_event_t *rev, *wev; ngx_connection_t *c; ngx_epoch_msec_t delta; struct dvpoll dvp; @@ -476,16 +477,16 @@ int ngx_devpoll_process_events(ngx_cycle event_list[i].events, event_list[i].revents); } - if ((event_list[i].events & (POLLOUT|POLLERR|POLLHUP)) - && c->write->active) - { - c->write->ready = 1; + wev = c->write; + + if ((event_list[i].events & (POLLOUT|POLLERR|POLLHUP)) && wev->active) { + wev->ready = 1; if (!ngx_threaded && !ngx_accept_mutex_held) { - c->write->event_handler(c->write); + wev->event_handler(wev); } else { - ngx_post_event(c->write); + ngx_post_event(wev); } } @@ -495,21 +496,21 @@ int ngx_devpoll_process_events(ngx_cycle * if the accept event is the last one. */ - if ((event_list[i].events & (POLLIN|POLLERR|POLLHUP)) - && c->read->active) - { - c->read->ready = 1; + rev = c->read; + + if ((event_list[i].events & (POLLIN|POLLERR|POLLHUP)) && rev->active) { + rev->ready = 1; if (!ngx_threaded && !ngx_accept_mutex_held) { - c->read->event_handler(c->read); + rev->event_handler(rev); - } else if (!c->read->accept) { - ngx_post_event(c->read); + } else if (!rev->accept) { + ngx_post_event(rev); } else if (ngx_accept_disabled <= 0) { ngx_mutex_unlock(ngx_posted_events_mutex); - c->read->event_handler(c->read); + c->read->event_handler(rev); if (ngx_accept_disabled > 0) { ngx_accept_mutex_unlock(); 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 @@ -75,7 +75,7 @@ static void ngx_epoll_done(ngx_cycle_t * static int ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags); static int ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags); static int ngx_epoll_add_connection(ngx_connection_t *c); -static int ngx_epoll_del_connection(ngx_connection_t *c); +static int ngx_epoll_del_connection(ngx_connection_t *c, u_int flags); static int ngx_epoll_process_events(ngx_cycle_t *cycle); static void *ngx_epoll_create_conf(ngx_cycle_t *cycle); @@ -111,8 +111,8 @@ ngx_event_module_t ngx_epoll_module_ctx ngx_epoll_del_event, /* delete an event */ ngx_epoll_add_event, /* enable an event */ ngx_epoll_del_event, /* disable an event */ - NULL, /* add an connection */ - NULL, /* delete an connection */ + ngx_epoll_add_connection, /* add an connection */ + ngx_epoll_del_connection, /* delete an connection */ NULL, /* process the changes */ ngx_epoll_process_events, /* process the events */ ngx_epoll_init, /* init the events */ @@ -124,9 +124,9 @@ 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 process */ + NGX_EVENT_MODULE, /* module type */ + NULL, /* init module */ + NULL /* init process */ }; @@ -174,7 +174,7 @@ static int ngx_epoll_init(ngx_cycle_t *c ngx_event_flags = NGX_USE_LEVEL_EVENT #endif |NGX_HAVE_GREEDY_EVENT - |NGX_HAVE_INSTANCE_EVENT; + |NGX_USE_EPOLL_EVENT; return NGX_OK; } @@ -306,7 +306,6 @@ static int ngx_epoll_del_event(ngx_event } -#if 0 static int ngx_epoll_add_connection(ngx_connection_t *c) { struct epoll_event ee; @@ -330,14 +329,41 @@ static int ngx_epoll_add_connection(ngx_ } -static int ngx_epoll_del_connection(ngx_connection_t *c) +static int ngx_epoll_del_connection(ngx_connection_t *c, u_int flags) { + int op; + struct epoll_event ee; + + /* + * when the file descriptor is closed the epoll automatically deletes + * it from its queue so we do not need to delete explicity the event + * before the closing the file descriptor + */ + + if (flags & NGX_CLOSE_EVENT) { + c->read->active = 0; + c->write->active = 0; + return NGX_OK; + } + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "epoll del connection: fd:%d", c->fd); + + op = EPOLL_CTL_DEL; + ee.events = 0; + ee.data.ptr = NULL; + + if (epoll_ctl(ep, op, c->fd, &ee) == -1) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + "epoll_ctl(%d, %d) failed", op, c->fd); + return NGX_ERROR; + } + c->read->active = 0; c->write->active = 0; return NGX_OK; } -#endif int ngx_epoll_process_events(ngx_cycle_t *cycle) @@ -349,6 +375,7 @@ int ngx_epoll_process_events(ngx_cycle_t ngx_err_t err; ngx_log_t *log; ngx_msec_t timer; + ngx_event_t *rev, *wev; struct timeval tv; ngx_connection_t *c; ngx_epoch_msec_t delta; @@ -356,6 +383,19 @@ int ngx_epoll_process_events(ngx_cycle_t for ( ;; ) { timer = ngx_event_find_timer(); +#if (NGX_THREADS) + + if (timer == NGX_TIMER_ERROR) { + return NGX_ERROR; + } + + if (timer == NGX_TIMER_INFINITE || timer > 500) { + timer = 500; + break; + } + +#endif + if (timer != 0) { break; } @@ -365,6 +405,10 @@ int ngx_epoll_process_events(ngx_cycle_t ngx_event_expire_timers((ngx_msec_t) (ngx_elapsed_msec - ngx_old_elapsed_msec)); + + if (ngx_posted_events && ngx_threaded) { + ngx_wakeup_worker_thread(cycle); + } } /* NGX_TIMER_INFINITE == INFTIM */ @@ -438,12 +482,18 @@ int ngx_epoll_process_events(ngx_cycle_t return NGX_ERROR; } - if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { - ngx_accept_mutex_unlock(); - return NGX_ERROR; + if (events > 0) { + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + ngx_accept_mutex_unlock(); + return NGX_ERROR; + } + + lock = 1; + + } else { + lock =0; } - lock = 1; log = cycle->log; for (i = 0; i < events; i++) { @@ -452,15 +502,9 @@ int ngx_epoll_process_events(ngx_cycle_t instance = (uintptr_t) c & 1; c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1); - if (event_list[i].events & EPOLLIN) { - c->read->returned_instance = instance; - } + rev = c->read; - if (event_list[i].events & EPOLLOUT) { - c->write->returned_instance = instance; - } - - if (c->read->instance != instance) { + if (c->fd == -1 || rev->instance != instance) { /* * the stale event from a file descriptor @@ -492,16 +536,24 @@ int ngx_epoll_process_events(ngx_cycle_t c->fd, event_list[i].events); } + wev = c->write; + if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP)) - && c->write->active) + && wev->active) { - c->write->ready = 1; - - if (!ngx_threaded && !ngx_accept_mutex_held) { - c->write->event_handler(c->write); + if (ngx_threaded) { + wev->posted_ready = 1; + ngx_post_event(wev); } else { - ngx_post_event(c->write); + wev->ready = 1; + + if (!ngx_accept_mutex_held) { + wev->event_handler(wev); + + } else { + ngx_post_event(wev); + } } } @@ -512,21 +564,29 @@ int ngx_epoll_process_events(ngx_cycle_t */ if ((event_list[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP)) - && c->read->active) + && rev->active) { - c->read->ready = 1; + if (ngx_threaded && !rev->accept) { + rev->posted_ready = 1; + + ngx_post_event(rev); + + continue; + } + + rev->ready = 1; if (!ngx_threaded && !ngx_accept_mutex_held) { - c->read->event_handler(c->read); + rev->event_handler(rev); - } else if (!c->read->accept) { - ngx_post_event(c->read); + } else if (!rev->accept) { + ngx_post_event(rev); } else if (ngx_accept_disabled <= 0) { ngx_mutex_unlock(ngx_posted_events_mutex); - c->read->event_handler(c->read); + rev->event_handler(rev); if (ngx_accept_disabled > 0) { ngx_accept_mutex_unlock(); @@ -560,8 +620,13 @@ int ngx_epoll_process_events(ngx_cycle_t ngx_event_expire_timers((ngx_msec_t) delta); } - if (!ngx_threaded) { - ngx_event_process_posted(cycle); + if (ngx_posted_events) { + if (ngx_threaded) { + ngx_wakeup_worker_thread(cycle); + + } else { + ngx_event_process_posted(cycle); + } } return NGX_OK; 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 @@ -60,6 +60,7 @@ ngx_event_module_t ngx_iocp_module_ctx NULL, /* disable an event */ NULL, /* add an connection */ ngx_iocp_del_connection, /* delete an connection */ + NULL, /* process the changes */ ngx_iocp_process_events, /* process the events */ ngx_iocp_init, /* init the events */ ngx_iocp_done /* done the events */ @@ -73,7 +74,7 @@ ngx_module_t ngx_iocp_module = { ngx_iocp_commands, /* module directives */ NGX_EVENT_MODULE, /* module type */ NULL, /* init module */ - NULL /* init child */ + NULL /* init process */ }; 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 @@ -421,6 +421,7 @@ static ngx_int_t ngx_kqueue_process_even timer = ngx_event_find_timer(); #if (NGX_THREADS) + if (timer == NGX_TIMER_ERROR) { return NGX_ERROR; } @@ -442,7 +443,9 @@ static ngx_int_t ngx_kqueue_process_even ngx_event_expire_timers((ngx_msec_t) (ngx_elapsed_msec - ngx_old_elapsed_msec)); - /* TODO: if ngx_threaded then wake up the worker thread */ + if (ngx_posted_events && ngx_threaded) { + ngx_wakeup_worker_thread(cycle); + } } ngx_old_elapsed_msec = ngx_elapsed_msec; 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 @@ -14,6 +14,7 @@ static void ngx_poll_done(ngx_cycle_t *c static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags); static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags); static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle); +static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf); static struct pollfd *event_list; @@ -31,7 +32,7 @@ static ngx_str_t poll_name = ngx_stri ngx_event_module_t ngx_poll_module_ctx = { &poll_name, NULL, /* create configuration */ - NULL, /* init configuration */ + ngx_poll_init_conf, /* init configuration */ { ngx_poll_add_event, /* add an event */ @@ -577,3 +578,27 @@ static ngx_int_t ngx_poll_process_events return nready; } + + +static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf) +{ + ngx_event_conf_t *ecf; + + ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); + + if (ecf->use != ngx_poll_module.ctx_index) { + return NGX_CONF_OK; + } + +#if (NGX_THREADS) + + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "poll() is not supported in the threaded mode"); + return NGX_CONF_ERROR; + +#else + + return NGX_CONF_OK; + +#endif +} 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 @@ -158,9 +158,7 @@ static ngx_int_t ngx_rtsig_init(ngx_cycl ngx_event_actions = ngx_rtsig_module_ctx.actions; - ngx_event_flags = NGX_USE_RTSIG_EVENT - |NGX_HAVE_GREEDY_EVENT - |NGX_HAVE_INSTANCE_EVENT; + ngx_event_flags = NGX_USE_RTSIG_EVENT|NGX_HAVE_GREEDY_EVENT; return NGX_OK; } @@ -275,6 +273,7 @@ ngx_int_t ngx_rtsig_process_events(ngx_c ngx_msec_t timer; ngx_err_t err; siginfo_t si; + ngx_event_t *rev, *wev; struct timeval tv; struct timespec ts, *tp; struct sigaction sa; @@ -290,6 +289,19 @@ ngx_int_t ngx_rtsig_process_events(ngx_c for ( ;; ) { timer = ngx_event_find_timer(); +#if (NGX_THREADS) + + if (timer == NGX_TIMER_ERROR) { + return NGX_ERROR; + } + + if (timer == NGX_TIMER_INFINITE || timer > 500) { + timer = 500; + break; + } + +#endif + if (timer != 0) { break; } @@ -299,6 +311,10 @@ ngx_int_t ngx_rtsig_process_events(ngx_c ngx_event_expire_timers((ngx_msec_t) (ngx_elapsed_msec - ngx_old_elapsed_msec)); + + if (ngx_posted_events && ngx_threaded) { + ngx_wakeup_worker_thread(cycle); + } } expire = 1; @@ -340,7 +356,7 @@ ngx_int_t ngx_rtsig_process_events(ngx_c ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "rtsig timer: %d", timer); - /* Linux sigwaitinfo() is sigtimedwait() with the NULL timeout pointer */ + /* Linux's sigwaitinfo() is sigtimedwait() with the NULL timeout pointer */ signo = sigtimedwait(&set, &si, tp); @@ -400,14 +416,8 @@ ngx_int_t ngx_rtsig_process_events(ngx_c instance = signo - rtscf->signo; - if (si.si_band & POLLIN) { - c->read->returned_instance = instance; - } + rev = c->read; - if (si.si_band & POLLOUT) { - c->write->returned_instance = instance; - } - if (c->read->instance != instance) { /* @@ -424,47 +434,62 @@ ngx_int_t ngx_rtsig_process_events(ngx_c } if (si.si_band & (POLLIN|POLLHUP|POLLERR)) { - if (c->read->active) { - c->read->ready = 1; - - if (!ngx_threaded && !ngx_accept_mutex_held) { - c->read->event_handler(c->read); + if (rev->active) { - } else if (c->read->accept) { - if (ngx_accept_disabled <= 0) { - c->read->event_handler(c->read); - } - - } else { + if (ngx_threaded && !rev->accept) { if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { ngx_accept_mutex_unlock(); return NGX_ERROR; } - ngx_post_event(c->read); + rev->posted_ready = 1; + ngx_post_event(rev); ngx_mutex_unlock(ngx_posted_events_mutex); + + } else { + rev->ready = 1; + + if (!ngx_threaded && !ngx_accept_mutex_held) { + rev->event_handler(rev); + + } else if (rev->accept) { + if (ngx_accept_disabled <= 0) { + rev->event_handler(rev); + } + + } else { + ngx_post_event(rev); + } } } } - if (si.si_band & (POLLOUT|POLLHUP|POLLERR)) { - if (c->write->active) { - c->write->ready = 1; + wev = c->write; - if (!ngx_threaded && !ngx_accept_mutex_held) { - c->write->event_handler(c->write); + if (si.si_band & (POLLOUT|POLLHUP|POLLERR)) { + if (wev->active) { - } else { - + if (ngx_threaded) { if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { ngx_accept_mutex_unlock(); return NGX_ERROR; } - ngx_post_event(c->write); + wev->posted_ready = 1; + ngx_post_event(wev); ngx_mutex_unlock(ngx_posted_events_mutex); + + } else { + wev->ready = 1; + + if (!ngx_threaded && !ngx_accept_mutex_held) { + wev->event_handler(wev); + + } else { + ngx_post_event(wev); + } } } } @@ -512,8 +537,13 @@ ngx_int_t ngx_rtsig_process_events(ngx_c ngx_event_expire_timers((ngx_msec_t) delta); } - if (!ngx_threaded) { - ngx_event_process_posted(cycle); + if (ngx_posted_events) { + if (ngx_threaded) { + ngx_wakeup_worker_thread(cycle); + + } else { + ngx_event_process_posted(cycle); + } } if (signo == -1) { @@ -532,6 +562,7 @@ static ngx_int_t ngx_rtsig_process_overf size_t len; ngx_int_t tested, n, i; ngx_err_t err; + ngx_event_t *rev, *wev; ngx_connection_t *c; ngx_rtsig_conf_t *rtscf; @@ -587,60 +618,60 @@ static ngx_int_t ngx_rtsig_process_overf cycle->log, 0, "poll() failed while the overflow recover"); - if (err == NGX_EINTR) { - continue; + if (err != NGX_EINTR) { + break; } } - - break; } if (ready <= 0) { continue; } + if (n) { + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + return NGX_ERROR; + } + } + for (i = 0; i < n; i++) { c = &cycle->connections[overflow_list[i].fd]; + rev = c->read; + if (overflow_list[i].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) { tested++; - c->read->ready = 1; - if (!ngx_threaded) { - c->read->event_handler(c->read); + if (ngx_threaded) { + rev->posted_ready = 1; + ngx_post_event(rev); } 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); + rev->ready = 1; + rev->event_handler(rev); } } + wev = c->write; + if (overflow_list[i].revents & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { tested++; - c->write->ready = 1; - - if (!ngx_threaded) { - c->write->event_handler(c->write); + + if (ngx_threaded) { + wev->posted_ready = 1; + ngx_post_event(wev); } else { - if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { - return NGX_ERROR; - } - - ngx_post_event(c->write); - c->write->returned_instance = c->write->instance; - - ngx_mutex_unlock(ngx_posted_events_mutex); + wev->ready = 1; + wev->event_handler(wev); } } } + if (n) { + ngx_mutex_unlock(ngx_posted_events_mutex); + } + if (tested >= rtscf->overflow_test) { /* @@ -683,8 +714,13 @@ static ngx_int_t ngx_rtsig_process_overf } } - if (!ngx_threaded) { - ngx_event_process_posted(cycle); + if (ngx_posted_events) { + if (ngx_threaded) { + ngx_wakeup_worker_thread(cycle); + + } else { + ngx_event_process_posted(cycle); + } } ngx_log_error(NGX_LOG_INFO, cycle->log, 0, 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 @@ -15,7 +15,6 @@ static void ngx_select_done(ngx_cycle_t static ngx_int_t ngx_select_add_event(ngx_event_t *ev, int event, u_int flags); static ngx_int_t ngx_select_del_event(ngx_event_t *ev, int event, u_int flags); static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle); - static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf); @@ -605,5 +604,11 @@ static char *ngx_select_init_conf(ngx_cy } #endif +#if (NGX_THREADS) + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "select() is not supported in the threaded mode"); + return NGX_CONF_ERROR; +#else return NGX_CONF_OK; +#endif } 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 @@ -41,9 +41,7 @@ struct ngx_event_s { unsigned oneshot:1; /* used to detect the stale events in kqueue, rt signals and epoll */ - unsigned use_instance:1; unsigned instance:1; - unsigned returned_instance:1; /* * the event was passed or would be passed to a kernel; @@ -76,6 +74,10 @@ struct ngx_event_s { /* the pending eof reported by kqueue or in aio chain operation */ unsigned pending_eof:1; +#if !(NGX_THREADS) + unsigned posted_ready:1; +#endif + #if (WIN32) /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was succesfull */ unsigned accept_context_updated:1; @@ -244,39 +246,32 @@ extern ngx_event_actions_t ngx_event_a #define NGX_HAVE_LOWAT_EVENT 0x00000010 /* - * The event filter allows to pass instance information to check stale events - - * kqueue, epoll, rt signals. - */ -#define NGX_HAVE_INSTANCE_EVENT 0x00000020 - -/* * The event filter requires to do i/o operation until EAGAIN - * epoll, rt signals. */ -#define NGX_HAVE_GREEDY_EVENT 0x00000040 +#define NGX_HAVE_GREEDY_EVENT 0x00000020 /* - * The event filter notifies only the changes (the edges) - * but not an initial level - early epoll patches. + * The event filter is epoll, */ -#define NGX_USE_EDGE_EVENT 0x00000080 +#define NGX_USE_EPOLL_EVENT 0x00000040 /* * No need to add or delete the event filters - rt signals. */ -#define NGX_USE_RTSIG_EVENT 0x00000100 +#define NGX_USE_RTSIG_EVENT 0x00000080 /* * No need to add or delete the event filters - overlapped, aio_read, * aioread, io_submit. */ -#define NGX_USE_AIO_EVENT 0x00000200 +#define NGX_USE_AIO_EVENT 0x00000100 /* * Need to add socket or handle only once - i/o completion port. * It also requires HAVE_AIO and NGX_USE_AIO_EVENT to be set. */ -#define NGX_USE_IOCP_EVENT 0x00000400 +#define NGX_USE_IOCP_EVENT 0x00000200 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 @@ -16,7 +16,7 @@ static size_t ngx_accept_log_error(void void ngx_event_accept(ngx_event_t *ev) { - ngx_uint_t instance, rinstance, winstance, accepted; + ngx_uint_t instance, accepted; socklen_t len; struct sockaddr *sa; ngx_err_t err; @@ -30,7 +30,7 @@ void ngx_event_accept(ngx_event_t *ev) ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); - if (ngx_event_flags & (NGX_USE_EDGE_EVENT|NGX_USE_RTSIG_EVENT)) { + if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { ev->available = 1; } else if (!(ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)) { @@ -94,8 +94,7 @@ void ngx_event_accept(ngx_event_t *ev) err = ngx_socket_errno; if (err == NGX_EAGAIN) { - if (!(ngx_event_flags - & (NGX_USE_EDGE_EVENT|NGX_USE_RTSIG_EVENT))) + if (!(ngx_event_flags & NGX_USE_RTSIG_EVENT)) { ngx_log_error(NGX_LOG_NOTICE, log, err, "EAGAIN after %d accepted connection(s)", @@ -207,8 +206,6 @@ void ngx_event_accept(ngx_event_t *ev) #endif instance = rev->instance; - rinstance = rev->returned_instance; - winstance = wev->returned_instance; #if (NGX_THREADS) @@ -231,15 +228,8 @@ void ngx_event_accept(ngx_event_t *ev) c->sockaddr = sa; c->socklen = len; - if (ngx_event_flags & NGX_HAVE_INSTANCE_EVENT) { - rev->use_instance = 1; - rev->instance = (u_char) !instance; - rev->returned_instance = (u_char) rinstance; - - wev->use_instance = 1; - wev->instance = (u_char) !instance; - wev->returned_instance = (u_char) winstance; - } + rev->instance = !instance; + wev->instance = !instance; rev->index = NGX_INVALID_INDEX; wev->index = NGX_INVALID_INDEX; @@ -256,9 +246,7 @@ void ngx_event_accept(ngx_event_t *ev) wev->write = 1; wev->ready = 1; - if (ngx_event_flags - & (NGX_USE_AIO_EVENT|NGX_USE_EDGE_EVENT|NGX_USE_RTSIG_EVENT)) - { + if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT)) { /* epoll, rtsig, aio, iocp */ rev->ready = 1; } @@ -267,10 +255,6 @@ void ngx_event_accept(ngx_event_t *ev) rev->ready = 1; } - if (rev->ready) { - rev->returned_instance = rev->instance; - } - c->ctx = ls->ctx; c->servers = ls->servers; @@ -318,7 +302,7 @@ void ngx_event_accept(ngx_event_t *ev) } #endif - if (ngx_add_conn) { + if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { if (ngx_add_conn(c) == NGX_ERROR) { if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, 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 @@ -11,7 +11,7 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc) { int rc; - ngx_uint_t instance, rinstance, winstance; + ngx_uint_t instance; u_int event; time_t now; ngx_err_t err; @@ -30,11 +30,17 @@ int ngx_event_connect_peer(ngx_peer_conn /* cached connection */ - pc->connection = pc->peers->cached[pc->peers->last_cached]; + c = pc->peers->cached[pc->peers->last_cached]; pc->peers->last_cached--; /* ngx_unlock_mutex(pc->peers->mutex); */ +#if (NGX_THREADS) + c->read->lock = c->read->own_lock; + c->write->lock = c->write->own_lock; +#endif + + pc->connection = c; pc->cached = 1; return NGX_OK; } @@ -180,8 +186,6 @@ int ngx_event_connect_peer(ngx_peer_conn #endif instance = rev->instance; - rinstance = rev->returned_instance; - winstance = wev->returned_instance; #if (NGX_THREADS) @@ -198,15 +202,8 @@ int ngx_event_connect_peer(ngx_peer_conn ngx_memzero(rev, sizeof(ngx_event_t)); ngx_memzero(wev, sizeof(ngx_event_t)); - if (ngx_event_flags & NGX_HAVE_INSTANCE_EVENT) { - rev->use_instance = 1; - rev->instance = (u_char) !instance; - rev->returned_instance = (u_char) rinstance; - - wev->use_instance = 1; - wev->instance = (u_char) !instance; - wev->returned_instance = (u_char) winstance; - } + rev->instance = !instance; + wev->instance = !instance; rev->index = NGX_INVALID_INDEX; wev->index = NGX_INVALID_INDEX; diff --git a/src/event/ngx_event_posted.c b/src/event/ngx_event_posted.c --- a/src/event/ngx_event_posted.c +++ b/src/event/ngx_event_posted.c @@ -73,11 +73,8 @@ void ngx_wakeup_worker_thread(ngx_cycle_ ngx_int_t ngx_event_thread_process_posted(ngx_cycle_t *cycle) { - ngx_tls_t *tls; ngx_event_t *ev; - tls = ngx_thread_get_tls(); - for ( ;; ) { ev = (ngx_event_t *) ngx_posted_events; @@ -136,8 +133,6 @@ ngx_int_t ngx_event_thread_process_poste ngx_mutex_unlock(ngx_posted_events_mutex); - tls->event = ev; - ev->event_handler(ev); if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -136,7 +136,6 @@ void ngx_event_expire_timers(ngx_msec_t } ev->posted_timedout = 1; - ev->returned_instance = ev->instance; ngx_post_event(ev); ngx_mutex_unlock(ngx_posted_events_mutex); 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 @@ -456,7 +456,7 @@ ngx_int_t ngx_http_find_location_config( ngx_http_core_loc_conf_t *clcf, **clcfp; ngx_http_core_srv_conf_t *cscf; #if (HAVE_PCRE) - ngx_uint_t exact; + ngx_uint_t exact; #endif cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); diff --git a/src/os/unix/ngx_channel.c b/src/os/unix/ngx_channel.c --- a/src/os/unix/ngx_channel.c +++ b/src/os/unix/ngx_channel.c @@ -194,6 +194,13 @@ ngx_int_t ngx_add_channel_event(ngx_cycl rev->data = c; wev->data = c; +#if (NGX_THREADS) + rev->lock = &c->lock; + wev->lock = &c->lock; + rev->own_lock = &c->lock; + wev->own_lock = &c->lock; +#endif + ev = (event == NGX_READ_EVENT) ? rev : wev; ev->event_handler = handler; diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -12,10 +12,12 @@ typedef int ngx_err_t; #define NGX_ESRCH ESRCH #define NGX_EINTR EINTR #define NGX_ECHILD ECHILD +#define NGX_ENOMEM ENOMEM #define NGX_EACCES EACCES #define NGX_EBUSY EBUSY #define NGX_EEXIST EEXIST #define NGX_ENOTDIR ENOTDIR +#define NGX_EINVAL EINVAL #define NGX_EPIPE EPIPE #define NGX_EAGAIN EWOULDBLOCK #define NGX_EINPROGRESS EINPROGRESS diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c --- a/src/os/unix/ngx_freebsd_rfork_thread.c +++ b/src/os/unix/ngx_freebsd_rfork_thread.c @@ -30,18 +30,20 @@ */ -char *ngx_freebsd_kern_usrstack; -size_t ngx_thread_stack_size; +char *ngx_freebsd_kern_usrstack; +size_t ngx_thread_stack_size; -static size_t rz_size; -static size_t usable_stack_size; -static char *last_stack; +static size_t rz_size; +static size_t usable_stack_size; +static char *last_stack; -static ngx_uint_t nthreads; -static ngx_uint_t max_threads; -static ngx_tid_t *tids; /* the threads tids array */ -void **ngx_tls; /* the threads tls's array */ +static ngx_uint_t nthreads; +static ngx_uint_t max_threads; + +static ngx_uint_t nkeys; +static ngx_tid_t *tids; /* the threads tids array */ +void **ngx_tls; /* the threads tls's array */ /* the thread-safe libc errno */ @@ -236,7 +238,9 @@ ngx_int_t ngx_init_threads(int n, size_t /* create the threads tls's array */ - if (!(ngx_tls = ngx_calloc((n + 1) * sizeof(void *), cycle->log))) { + ngx_tls = ngx_calloc(NGX_THREAD_KEYS_MAX * (n + 1) * sizeof(void *), + cycle->log); + if (ngx_tls == NULL) { return NGX_ERROR; } @@ -270,11 +274,26 @@ ngx_tid_t ngx_thread_self() } -ngx_int_t ngx_thread_set_tls(void *value) +ngx_int_t ngx_thread_key_create(ngx_tls_key_t *key) { - ngx_tls[ngx_gettid()] = value; + if (nkeys >= NGX_THREAD_KEYS_MAX) { + return NGX_ENOMEM; + } + + *key = nkeys++; + + return 0; +} - return NGX_OK; + +ngx_int_t ngx_thread_set_tls(ngx_tls_key_t key, void *value) +{ + if (key >= NGX_THREAD_KEYS_MAX) { + return NGX_EINVAL; + } + + ngx_tls[key * NGX_THREAD_KEYS_MAX + ngx_gettid()] = value; + return 0; } diff --git a/src/os/unix/ngx_freebsd_rfork_thread.h b/src/os/unix/ngx_freebsd_rfork_thread.h --- a/src/os/unix/ngx_freebsd_rfork_thread.h +++ b/src/os/unix/ngx_freebsd_rfork_thread.h @@ -13,14 +13,6 @@ typedef pid_t ngx_tid_t; #define ngx_log_tid 0 #define TID_T_FMT PID_T_FMT - - -extern void **ngx_tls; - -#define ngx_thread_create_tls() 0 -#define ngx_thread_create_tls_n "" -#define ngx_thread_get_tls() ngx_tls[ngx_gettid()] -ngx_int_t ngx_thread_set_tls(void *value); #define NGX_MUTEX_LIGHT 1 @@ -87,6 +79,29 @@ static inline int ngx_gettid() ngx_tid_t ngx_thread_self(); +typedef ngx_uint_t ngx_tls_key_t; + +#define NGX_THREAD_KEYS_MAX 16 + +extern void **ngx_tls; + +ngx_int_t ngx_thread_key_create(ngx_tls_key_t *key); +#define ngx_thread_key_create_n "the tls key creation" + +ngx_int_t ngx_thread_set_tls(ngx_tls_key_t key, void *value); +#define ngx_thread_set_tls_n "the tls key setting" + + +static void *ngx_thread_get_tls(ngx_tls_key_t key) +{ + if (key >= NGX_THREAD_KEYS_MAX) { + return NULL; + } + + return ngx_tls[key * NGX_THREAD_KEYS_MAX + ngx_gettid()]; +} + + #define ngx_mutex_trylock(m) ngx_mutex_dolock(m, 1) #define ngx_mutex_lock(m) ngx_mutex_dolock(m, 0) ngx_int_t ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try); 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 @@ -526,6 +526,7 @@ static void ngx_master_exit(ngx_cycle_t static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { sigset_t set; + ngx_err_t err; ngx_int_t n; ngx_uint_t i; ngx_listening_t *ls; @@ -637,6 +638,14 @@ static void ngx_worker_process_cycle(ngx exit(2); } + err = ngx_thread_key_create(&ngx_core_tls_key); + if (err != 0) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, err, + ngx_thread_key_create_n " failed"); + /* fatal */ + exit(2); + } + for (n = 0; n < ngx_threads_n; n++) { if (!(ngx_threads[n].cv = ngx_cond_init(cycle->log))) { @@ -829,7 +838,7 @@ static void* ngx_worker_thread_cycle(voi sigset_t set; ngx_err_t err; - ngx_tls_t *tls; + ngx_core_tls_t *tls; ngx_cycle_t *cycle; struct timeval tv; @@ -854,19 +863,17 @@ static void* ngx_worker_thread_cycle(voi ngx_setthrtitle("worker thread"); - if (!(tls = ngx_calloc(sizeof(ngx_tls_t), cycle->log))) { + if (!(tls = ngx_calloc(sizeof(ngx_core_tls_t), cycle->log))) { return (void *) 1; } - err = ngx_thread_create_tls(); + err = ngx_thread_set_tls(ngx_core_tls_key, tls); if (err != 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - ngx_thread_create_tls_n " failed"); + ngx_thread_set_tls_n " failed"); return (void *) 1; } - ngx_thread_set_tls(tls); - if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { return (void *) 1; } @@ -883,7 +890,7 @@ static void* ngx_worker_thread_cycle(voi ngx_mutex_unlock(ngx_posted_events_mutex); - ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, ngx_errno, + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "thread %d is done", ngx_thread_self()); return (void *) 0; @@ -899,8 +906,10 @@ static void* ngx_worker_thread_cycle(voi return (void *) 1; } - if (ngx_process_changes(cycle, 1) == NGX_ERROR) { - return (void *) 1; + if (ngx_process_changes) { + if (ngx_process_changes(cycle, 1) == NGX_ERROR) { + return (void *) 1; + } } } } diff --git a/src/os/unix/ngx_thread.h b/src/os/unix/ngx_thread.h --- a/src/os/unix/ngx_thread.h +++ b/src/os/unix/ngx_thread.h @@ -16,20 +16,22 @@ #else /* use pthreads */ #include -#include -typedef pthread_t ngx_tid_t; +typedef pthread_t ngx_tid_t; -#define ngx_thread_self() pthread_self() -#define ngx_log_tid (int) ngx_thread_self() +#define ngx_thread_self() pthread_self() +#define ngx_log_tid (int) ngx_thread_self() -#define TID_T_FMT PTR_FMT +#define TID_T_FMT PTR_FMT -#define ngx_thread_create_tls() pthread_key_create(0, NULL) -#define ngx_thread_create_tls_n "pthread_key_create(0, NULL)" -#define ngx_thread_get_tls() pthread_getspecific(0) -#define ngx_thread_set_tls(v) pthread_setspecific(0, v) +typedef pthread_key_t ngx_tls_key_t; + +#define ngx_thread_key_create(key) pthread_key_create(key, NULL) +#define ngx_thread_key_create_n "pthread_key_create()" +#define ngx_thread_set_tls pthread_setspecific +#define ngx_thread_set_tls_n "pthread_setspecific()" +#define ngx_thread_get_tls pthread_getspecific #define NGX_MUTEX_LIGHT 0 @@ -111,10 +113,5 @@ ngx_int_t ngx_cond_signal(ngx_cond_t *cv #endif -typedef struct { - ngx_event_t *event; -} ngx_tls_t; - - #endif /* _NGX_THREAD_H_INCLUDED_ */