# HG changeset patch # User Igor Sysoev # Date 1088747220 0 # Node ID 213f17e9f776c8b2feaccb8be067171121f6ff7e # Parent 018569a8f09c6272f820951a5741546d4ec38196 nginx-0.0.7-2004-07-02-09:47:00 import 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 @@ -236,7 +236,12 @@ static ngx_int_t ngx_kqueue_del_event(ng ev->active = 0; ev->disabled = 0; + + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { + return NGX_ERROR; + } ev->posted = 0; + ngx_mutex_unlock(ngx_posted_events_mutex); if (ngx_thread_main() && nchanges > 0 @@ -519,10 +524,24 @@ static ngx_int_t ngx_kqueue_process_even continue; } + if (ev->log && (ev->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { + ngx_kqueue_dump_event(ev->log, &event_list[i]); + } + ev->returned_instance = instance; - if (ev->log && (ev->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { - ngx_kqueue_dump_event(ev->log, &event_list[i]); + if (!ev->accept && (ngx_threaded || ngx_accept_mutex_held)) { + ev->posted_ready = 1; + ev->posted_available += event_list[i].data; + + if (event_list[i].flags & EV_EOF) { + ev->posted_eof = 1; + ev->posted_errno = event_list[i].fflags; + } + + ngx_post_event(ev); + + continue; } ev->available = event_list[i].data; @@ -532,10 +551,6 @@ static ngx_int_t ngx_kqueue_process_even ev->kq_errno = event_list[i].fflags; } - if (ev->oneshot && ev->timer_set) { - ngx_del_timer(ev); - } - ev->ready = 1; break; @@ -563,10 +578,12 @@ static ngx_int_t ngx_kqueue_process_even continue; } +#if 0 if (!ev->accept) { ngx_post_event(ev); continue; } +#endif if (ngx_accept_disabled > 0) { continue; 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 @@ -155,7 +155,26 @@ struct ngx_event_s { #if (NGX_THREADS) + ngx_atomic_t *lock; + + unsigned locked:1; + + unsigned posted_ready:1; + unsigned posted_timedout:1; + unsigned posted_eof:1; + +#if (HAVE_KQUEUE) + /* the pending errno reported by kqueue */ + int posted_errno; +#endif + +#if (HAVE_KQUEUE) || (HAVE_IOCP) + int posted_available; +#else + unsigned posted_available:1; +#endif + #endif 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 @@ -210,25 +210,6 @@ void ngx_event_accept(ngx_event_t *ev) rinstance = rev->returned_instance; winstance = wev->returned_instance; -#if (NGX_THREADS) - - /* - * We has to acquire the lock to avoid the race condition when - * the connection was just closed by another thread but its lock - * is not unlocked at this point and we got the same descriptor. - * - * The condition should be too rare. - */ - - if (ngx_trylock(&c->lock) == 0) { - - /* TODO: ngx_cycle->stat.accept.spinlock++; */ - - ngx_spinlock(&c->lock, 1000); - } - -#endif - ngx_memzero(rev, sizeof(ngx_event_t)); ngx_memzero(wev, sizeof(ngx_event_t)); ngx_memzero(c, sizeof(ngx_connection_t)); 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 @@ -76,6 +76,10 @@ ngx_int_t ngx_event_thread_process_poste return NGX_OK; } + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "posted event lock:%d " PTR_FMT, + *(ev->lock), ev->lock); + if (ngx_trylock(ev->lock) == 0) { ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, @@ -107,23 +111,31 @@ ngx_int_t ngx_event_thread_process_poste continue; } - ngx_mutex_unlock(ngx_posted_events_mutex); + ev->locked = 1; if (ev->posted) { + ev->ready = ev->posted_ready; + ev->timedout = ev->posted_timedout; + ev->available = ev->posted_available; + ev->kq_eof = ev->posted_eof; +#if (HAVE_KQUEUE) + ev->kq_errno = ev->posted_errno; +#endif ev->posted = 0; - if (!ev->timedout) { - ev->ready = 1; - } } + ngx_mutex_unlock(ngx_posted_events_mutex); + ev->event_handler(ev); - ngx_unlock(ev->lock); - if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { return NGX_ERROR; } + if (ev->locked) { + ngx_unlock(ev->lock); + } + break; } } diff --git a/src/event/ngx_event_posted.h b/src/event/ngx_event_posted.h --- a/src/event/ngx_event_posted.h +++ b/src/event/ngx_event_posted.h @@ -7,27 +7,11 @@ #include -typedef struct ngx_posted_events_s ngx_posted_event_t; - -struct ngx_posted_events_s { - ngx_event_t *event; - ngx_posted_event_t *next; - - unsigned instance:1; - unsigned ready:1; - unsigned timedout:1; - unsigned complete:1; -}; - - #define ngx_post_event(ev) \ if (!ev->posted) { \ ev->next = (ngx_event_t *) ngx_posted_events; \ ngx_posted_events = ev; \ ev->posted = 1; \ - } - -/* \ ngx_log_debug3(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, \ "POST: %08X %08X %08X", ngx_posted_events, \ @@ -35,7 +19,7 @@ struct ngx_posted_events_s { ((ngx_posted_events && ngx_posted_events->next) ? \ ngx_posted_events->next->next: 0)); \ \ -*/ +} /* \ 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 @@ -110,25 +110,26 @@ void ngx_event_expire_timers(ngx_msec_t #endif ev->timer_set = 0; - ev->timedout = 1; -#if (NGX_THREADS) - ngx_unlock(ev->lock); -#endif if (ngx_threaded) { if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { return; } + ev->posted_timedout = 1; ngx_post_event(ev); ngx_mutex_unlock(ngx_posted_events_mutex); continue; } + ev->timedout = 1; + ev->event_handler(ev); + continue; } + break; } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1739,16 +1739,31 @@ void ngx_http_close_connection(ngx_conne } } + /* + * we have to clean the connection information before the closing + * because another thread may reopen the same file descriptor + * before we clean the connection + */ + fd = c->fd; - c->fd = (ngx_socket_t) -1; c->data = NULL; ngx_destroy_pool(c->pool); - /* - * we has to clean the connection before the closing because another thread - * may reopen the same file descriptor before we clean the connection - */ +#if (NGX_THREADS) + + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_OK) { + ngx_unlock(&c->lock); + c->read->locked = 0; + c->write->locked = 0; + + ngx_mutex_unlock(ngx_posted_events_mutex); + } + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "connection lock: %d " PTR_FMT, c->lock, &c->lock); + +#endif if (ngx_close_socket(fd) == -1) { diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h --- a/src/os/unix/ngx_posix_config.h +++ b/src/os/unix/ngx_posix_config.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h --- a/src/os/unix/ngx_solaris_config.h +++ b/src/os/unix/ngx_solaris_config.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/src/os/win32/ngx_process.h b/src/os/win32/ngx_process.h --- a/src/os/win32/ngx_process.h +++ b/src/os/win32/ngx_process.h @@ -23,7 +23,7 @@ typedef struct { ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx); -#define ngx_sched_yeld() Sleep(0) +#define ngx_sched_yield() Sleep(0)