# HG changeset patch # User Igor Sysoev # Date 1076619430 0 # Node ID d30f2c39caae2e33ea464e6e627009d6a36ee02d # Parent 733dffa1fe976ede7fd5c8e2f2e011bb752e02c3 nginx-0.0.2-2004-02-12-23:57:10 import diff --git a/auto/os/linux b/auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -21,6 +21,7 @@ ngx_func_test="int efd = 0, fd = 1, n; if [ $ngx_found = yes ]; then have=HAVE_EPOLL . auto/have + have=HAVE_CLEAR_EVENT . auto/have CORE_SRCS="$CORE_SRCS $EPOLL_SRCS" EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE" EVENT_FOUND=YES 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 @@ -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 */ - ngx_epoll_add_connection, /* add an connection */ - ngx_epoll_del_connection, /* delete an connection */ + NULL, /* add an connection */ + NULL, /* delete an connection */ ngx_epoll_process_events, /* process the events */ ngx_epoll_init, /* init the events */ ngx_epoll_done, /* done the events */ @@ -167,7 +167,11 @@ static int ngx_epoll_init(ngx_cycle_t *c ngx_event_actions = ngx_epoll_module_ctx.actions; - ngx_event_flags = NGX_USE_EDGE_EVENT; +#if (HAVE_CLEAR_EVENT) + ngx_event_flags = NGX_USE_CLEAR_EVENT; +#else + ngx_event_flags = NGX_USE_LEVEL_EVENT; +#endif return NGX_OK; } @@ -191,33 +195,53 @@ static void ngx_epoll_done(ngx_cycle_t * static int ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags) { + int op, prev; + ngx_event_t *e; + ngx_connection_t *c; struct epoll_event ee; - ngx_connection_t *c; c = ev->data; -#if (NGX_READ_EVENT != EPOLLIN) || (NGX_WRITE_EVENT != EPOLLOUT) if (event == NGX_READ_EVENT) { + e = c->write; + prev = EPOLLOUT; +#if (NGX_READ_EVENT != EPOLLIN) event = EPOLLIN; - - } else { - event = EPOLLOUT; - } #endif - ee.events = event|EPOLLET; - ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance); + } else { + e = c->read; + prev = EPOLLIN; +#if (NGX_WRITE_EVENT != EPOLLOUT) + event = EPOLLOUT; +#endif + } + + if (e->active) { + op = EPOLL_CTL_MOD; + event |= prev; - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "epoll add event: fd:%d ev:%08X", c->fd, ee.events); + } else { + op = EPOLL_CTL_ADD; + } + + ee.events = event | flags; + ee.data.ptr = (void *) ((uintptr_t) c | ev->instance); - if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "epoll_ctl(EPOLL_CTL_MOD, %d) failed", c->fd); + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "epoll add event: fd:%d op:%d ev:%08X", + c->fd, op, ee.events); + + if (epoll_ctl(ep, op, c->fd, &ee) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, + "epoll_ctl(%d, %d) failed", op, c->fd); return NGX_ERROR; } ev->active = 1; +#if 0 + ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; +#endif return NGX_OK; } @@ -225,20 +249,51 @@ static int ngx_epoll_add_event(ngx_event static int ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags) { + int op, prev; + ngx_event_t *e; + ngx_connection_t *c; struct epoll_event ee; - ngx_connection_t *c; + + /* + * 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) { + ev->active = 0; + return NGX_OK; + } c = ev->data; - ee.events = 0; - ee.data.ptr = NULL; + if (event == NGX_READ_EVENT) { + e = c->write; + prev = EPOLLOUT; + + } else { + e = c->read; + prev = EPOLLIN; + } + + if (e->active) { + op = EPOLL_CTL_MOD; + ee.events = prev | flags; + ee.data.ptr = (void *) ((uintptr_t) c | ev->instance); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "epoll del event: fd:%d", c->fd); + } else { + op = EPOLL_CTL_DEL; + ee.events = 0; + ee.data.ptr = NULL; + } - if (epoll_ctl(ep, EPOLL_CTL_DEL, c->fd, &ee) == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "epoll_ctl(EPOLL_CTL_MOD, %d) failed", c->fd); + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "epoll del event: fd:%d op:%d ev:%08X", + c->fd, op, ee.events); + + if (epoll_ctl(ep, op, c->fd, &ee) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, + "epoll_ctl(%d, %d) failed", op, c->fd); return NGX_ERROR; } @@ -248,6 +303,7 @@ static int ngx_epoll_del_event(ngx_event } +#if 0 static int ngx_epoll_add_connection(ngx_connection_t *c) { struct epoll_event ee; @@ -278,6 +334,7 @@ static int ngx_epoll_del_connection(ngx_ return NGX_OK; } +#endif int ngx_epoll_process_events(ngx_log_t *log) 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 @@ -254,7 +254,7 @@ static int ngx_kqueue_del_event(ngx_even } /* - * when the file descriptor is closed a kqueue automatically deletes + * when the file descriptor is closed the kqueue automatically deletes * its filters so we do not need to delete explicity the event * before the closing the file descriptor. */ 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 @@ -146,7 +146,7 @@ static int ngx_poll_add_event(ngx_event_ } else { ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "poll index: %d", e->index); + "poll add index: %d", e->index); event_list[e->index].events |= event; ev->index = e->index; @@ -195,6 +195,10 @@ static int ngx_poll_del_event(ngx_event_ nevents--; if (ev->index < (u_int) nevents) { + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "index: copy event %d to %d", nevents, ev->index); + event_list[ev->index] = event_list[nevents]; c = &ngx_cycle->connections[event_list[nevents].fd]; @@ -219,20 +223,17 @@ static int ngx_poll_del_event(ngx_event_ } else { if (c->read->index == (u_int) nevents) { c->read->index = ev->index; - - } else if (c->write->index == (u_int) nevents) { - c->write->index = ev->index; + } - } else { - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "unexpected last event index"); + if (c->write->index == (u_int) nevents) { + c->write->index = ev->index; } } } } else { ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "poll index: %d", e->index); + "poll del index: %d", e->index); event_list[e->index].events &= ~event; } 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 @@ -176,18 +176,19 @@ extern ngx_event_actions_t ngx_event_a /* * The event filter requires to read/write the whole data - - * select, poll, /dev/poll, kqueue. + * select, poll, /dev/poll, kqueue, epoll. */ #define NGX_USE_LEVEL_EVENT 0x00000001 /* * The event filter is deleted after a notification without an additional - * syscall - select, poll, kqueue. + * syscall - select, poll, kqueue, epoll. */ #define NGX_USE_ONESHOT_EVENT 0x00000002 /* - * The event filter notifies only the changes and an initial level - kqueue. + * The event filter notifies only the changes and an initial level - + * kqueue, epoll. */ #define NGX_USE_CLEAR_EVENT 0x00000004 @@ -205,7 +206,7 @@ extern ngx_event_actions_t ngx_event_a /* * The event filter notifies only the changes (the edges) - * but not an initial level - epoll. + * but not an initial level - early epoll patches. */ #define NGX_USE_EDGE_EVENT 0x00000020 @@ -275,6 +276,27 @@ extern ngx_event_actions_t ngx_event_a #define NGX_DISABLE_EVENT EV_DISABLE +#elif (HAVE_DEVPOLL) + +#define NGX_READ_EVENT POLLIN +#define NGX_WRITE_EVENT POLLOUT + +#define NGX_LEVEL_EVENT 0 + + +#elif (HAVE_EPOLL) + +#define NGX_READ_EVENT EPOLLIN +#define NGX_WRITE_EVENT EPOLLOUT + +#define NGX_LEVEL_EVENT 0 +#define NGX_CLEAR_EVENT EPOLLET +#define NGX_ONESHOT_EVENT 0x70000000 +#if 0 +#define NGX_ONESHOT_EVENT EPOLLONESHOT +#endif + + #elif (HAVE_POLL) #define NGX_READ_EVENT POLLIN @@ -284,14 +306,6 @@ extern ngx_event_actions_t ngx_event_a #define NGX_ONESHOT_EVENT 1 -#elif (HAVE_DEVPOLL) - -#define NGX_READ_EVENT POLLIN -#define NGX_WRITE_EVENT POLLOUT - -#define NGX_LEVEL_EVENT 0 - - #else /* select */ #define NGX_READ_EVENT 0 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 @@ -142,7 +142,7 @@ void ngx_event_accept(ngx_event_t *ev) return; } - /* set a blocking mode for aio and non-blocking mode for others */ + /* set a blocking mode for aio and non-blocking mode for the others */ if (ngx_inherited_nonblocking) { if ((ngx_event_flags & NGX_USE_AIO_EVENT)) { 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 @@ -84,10 +84,10 @@ void ngx_http_init_connection(ngx_connec rev = c->read; rev->event_handler = ngx_http_init_request; - /* STUB: epoll */ c->write->event_handler = ngx_http_empty_handler; + /* STUB: epoll edge */ c->write->event_handler = ngx_http_empty_handler; if (rev->ready) { - /* deferred accept, aio, iocp, epoll */ + /* deferred accept, aio, iocp */ ngx_http_init_request(rev); return; } @@ -1180,6 +1180,8 @@ static void ngx_http_set_keepalive(ngx_h } h = c->buffer; + wev = c->write; + wev->event_handler = ngx_http_empty_handler; if (h->pos < h->last) { @@ -1214,8 +1216,6 @@ static void ngx_http_set_keepalive(ngx_h h->pos = h->last = h->start; rev->event_handler = ngx_http_keepalive_handler; - wev = c->write; - wev->event_handler = ngx_http_empty_handler; if (wev->active) { if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {