diff options
Diffstat (limited to 'src/event')
| -rw-r--r-- | src/event/modules/ngx_kqueue_module.c | 38 | ||||
| -rw-r--r-- | src/event/modules/ngx_kqueue_module.h | 2 | ||||
| -rw-r--r-- | src/event/modules/ngx_select_module.c | 71 | ||||
| -rw-r--r-- | src/event/modules/ngx_select_module.h | 2 | ||||
| -rw-r--r-- | src/event/ngx_event.c | 2 | ||||
| -rw-r--r-- | src/event/ngx_event.h | 15 | ||||
| -rw-r--r-- | src/event/ngx_event_accept.c | 83 | ||||
| -rw-r--r-- | src/event/ngx_event_close.c | 11 | ||||
| -rw-r--r-- | src/event/ngx_event_write.c | 3 |
9 files changed, 134 insertions, 93 deletions
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index 3b65f8063..4e82162a4 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -16,12 +16,14 @@ #endif - +/* should be per-thread */ static int kq; static struct kevent *change_list, *event_list; static int nchanges, nevents; static ngx_event_t timer_queue; +/* */ + int ngx_kqueue_init(int max_connections, ngx_log_t *log) { @@ -53,6 +55,7 @@ int ngx_kqueue_init(int max_connections, ngx_log_t *log) return NGX_OK; } + int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) { ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; @@ -60,22 +63,33 @@ int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) return ngx_kqueue_set_event(ev, event, EV_ADD | flags); } -int ngx_kqueue_del_event(ngx_event_t *ev, int event) + +int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) { ngx_event_t *e; - if (ev->index <= nchanges && change_list[ev->index].udata == ev) { - change_list[ev->index] = change_list[nchanges]; - e = (ngx_event_t *) change_list[ev->index].udata; - e->index = ev->index; - nchanges--; + if (ev->index < nchanges && change_list[ev->index].udata == ev) { + + ngx_connection_t *cn = (ngx_connection_t *) ev->data; + ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _ + cn->fd _ event); + + if (ev->index < --nchanges) { + e = (ngx_event_t *) change_list[nchanges].udata; + change_list[ev->index] = change_list[nchanges]; + e->index = ev->index; + } return NGX_OK; } + if (flags & NGX_CLOSE_EVENT) + return NGX_OK; + return ngx_kqueue_set_event(ev, event, EV_DELETE); } + int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags) { struct timespec ts = { 0, 0 }; @@ -110,13 +124,18 @@ int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags) return NGX_OK; } + int ngx_kqueue_process_events(ngx_log_t *log) { int events, i; - u_int timer = 0, delta = 0; + u_int timer, delta; ngx_event_t *ev; struct timeval tv; - struct timespec ts, *tp = NULL; + struct timespec ts, *tp; + + timer = 0; + delta = 0; + tp = NULL; if (timer_queue.timer_next != &timer_queue) { timer = timer_queue.timer_next->timer_delta; @@ -212,6 +231,7 @@ int ngx_kqueue_process_events(ngx_log_t *log) return NGX_OK; } + void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer) { ngx_event_t *e; diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h index ce2aacde3..c56192018 100644 --- a/src/event/modules/ngx_kqueue_module.h +++ b/src/event/modules/ngx_kqueue_module.h @@ -8,7 +8,7 @@ int ngx_kqueue_init(int max_connections, ngx_log_t *log); int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags); -int ngx_kqueue_del_event(ngx_event_t *ev, int event); +int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags); int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags); void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer); int ngx_kqueue_process_events(ngx_log_t *log); diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c index 54a5f7ee6..c87c59238 100644 --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -8,24 +8,26 @@ #include <ngx_event.h> #include <ngx_select_module.h> -static fd_set master_read_fd_set; -static fd_set master_write_fd_set; -static fd_set work_read_fd_set; -static fd_set work_write_fd_set; + +/* should be per-thread */ +static fd_set master_read_fd_set; +static fd_set master_write_fd_set; +static fd_set work_read_fd_set; +static fd_set work_write_fd_set; #if (WIN32) -static int max_read; -static int max_write; +static int max_read; +static int max_write; #else -static int max_fd; +static int max_fd; #endif -static int nevents; +static int nevents; static ngx_event_t **event_index; static ngx_event_t **ready_index; static ngx_event_t timer_queue; - +/* */ static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, ngx_log_t *log); @@ -121,12 +123,15 @@ int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) return NGX_OK; } -int ngx_select_del_event(ngx_event_t *ev, int event) +int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags) { ngx_connection_t *c; c = (ngx_connection_t *) ev->data; - ngx_log_debug(c->log, "del event: %d" _ c->fd); + if (ev->index == NGX_INVALID_INDEX) + return NGX_OK; + + ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event); #if (WIN32) if (event == NGX_READ_EVENT) { @@ -148,13 +153,13 @@ int ngx_select_del_event(ngx_event_t *ev, int event) max_fd = -1; #endif - nevents--; - - if (ev->index < nevents) { + if (ev->index < --nevents) { event_index[ev->index] = event_index[nevents]; event_index[ev->index]->index = ev->index; } + ev->index = NGX_INVALID_INDEX; + return NGX_OK; } @@ -162,7 +167,7 @@ int ngx_select_process_events(ngx_log_t *log) { int i, ready, found, nready; u_int timer, delta; - ngx_event_t *ev, *nx; + ngx_event_t *ev; ngx_connection_t *c; struct timeval tv, *tp; @@ -195,6 +200,15 @@ int ngx_select_process_events(ngx_log_t *log) } #endif +#if 1 + /* DEBUG */ + for (i = 0; i < nevents; i++) { + ev = event_index[i]; + c = (ngx_connection_t *) ev->data; + ngx_log_debug(log, "select: %d" _ c->fd); + } +#endif + ngx_log_debug(log, "select timer: %d" _ timer); #if (WIN32) @@ -222,17 +236,17 @@ int ngx_select_process_events(ngx_log_t *log) if (timer) { if (delta >= timer) { - for (ev = timer_queue.timer_next; - ev != &timer_queue && delta >= ev->timer_delta; - /* void */) - { + for ( ;; ) { + ev = timer_queue.timer_next; + + if (ev == &timer_queue || delta < ev->timer_delta) + break; + delta -= ev->timer_delta; - nx = ev->timer_next; ngx_del_timer(ev); ev->timedout = 1; - if (ev->event_handler(ev) == -1) + if (ev->event_handler(ev) == NGX_ERROR) ev->close_handler(ev); - ev = nx; } } else { @@ -249,15 +263,13 @@ int ngx_select_process_events(ngx_log_t *log) if (ev->write) { if (FD_ISSET(c->fd, &work_write_fd_set)) { - ngx_log_debug(log, "select write %d" _ - c->fd); + ngx_log_debug(log, "select write %d" _ c->fd); found = 1; } } else { if (FD_ISSET(c->fd, &work_read_fd_set)) { - ngx_log_debug(log, "select read %d" _ - c->fd); + ngx_log_debug(log, "select read %d" _ c->fd); found = 1; } } @@ -274,13 +286,14 @@ int ngx_select_process_events(ngx_log_t *log) if (ev->oneshot) { ngx_del_timer(ev); + if (ev->write) - ngx_select_del_event(ev, NGX_WRITE_EVENT); + ngx_select_del_event(ev, NGX_WRITE_EVENT, 0); else - ngx_select_del_event(ev, NGX_READ_EVENT); + ngx_select_del_event(ev, NGX_READ_EVENT, 0); } - if (ev->event_handler(ev) == -1) + if (ev->event_handler(ev) == NGX_ERROR) ev->close_handler(ev); ready--; diff --git a/src/event/modules/ngx_select_module.h b/src/event/modules/ngx_select_module.h index e2583d744..7460790fb 100644 --- a/src/event/modules/ngx_select_module.h +++ b/src/event/modules/ngx_select_module.h @@ -8,7 +8,7 @@ int ngx_select_init(int max_connections, ngx_log_t *log); int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags); -int ngx_select_del_event(ngx_event_t *ev, int event); +int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags); int ngx_select_set_event(ngx_event_t *ev, int filter, u_int flags); void ngx_select_add_timer(ngx_event_t *ev, ngx_msec_t timer); int ngx_select_process_events(ngx_log_t *log); diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 8e918f0ef..2d68af2a0 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -21,7 +21,7 @@ ngx_event_t *ngx_read_events, *ngx_write_events; #if !(USE_KQUEUE) -#if 0 +#if 1 ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT; #else ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT; diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 866911cf1..db2dc59b3 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -10,6 +10,8 @@ #include <ngx_alloc.h> #include <ngx_array.h> +#define NGX_INVALID_INDEX 0x80000000 + typedef struct ngx_event_s ngx_event_t; struct ngx_event_s { @@ -79,7 +81,7 @@ typedef enum { typedef struct { int (*add)(ngx_event_t *ev, int event, u_int flags); - int (*del)(ngx_event_t *ev, int event); + int (*del)(ngx_event_t *ev, int event, u_int flags); void (*timer)(ngx_event_t *ev, ngx_msec_t timer); int (*process)(ngx_log_t *log); int (*read)(ngx_event_t *ev, char *buf, size_t size); @@ -96,8 +98,12 @@ NGX_ONESHOT_EVENT select, poll, kqueue NGX_CLEAR_EVENT kqueue NGX_AIO_EVENT overlapped, aio_read, aioread no need to add or delete events + +NGX_CLOSE_EVENT kqueue: kqueue deletes events for file that closed */ +#define NGX_CLOSE_EVENT 1 + #if (HAVE_KQUEUE) #define NGX_READ_EVENT EVFILT_READ @@ -124,15 +130,12 @@ NGX_AIO_EVENT overlapped, aio_read, aioread #endif - #if (USE_KQUEUE) #define ngx_init_events ngx_kqueue_init #define ngx_process_events ngx_kqueue_process_events -#define ngx_kqueue_add_event(ev, event) \ - ngx_kqueue_set_event(ev, event, EV_ADD | flags) -#define ngx_kqueue_del_event(ev, event) \ - ngx_kqueue_set_event(ev, event, EV_DELETE) +#define ngx_add_event ngx_kqueue_add_event +#define ngx_del_event ngx_kqueue_add_event #define ngx_add_timer ngx_kqueue_add_timer #define ngx_event_recv ngx_event_recv_core diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index ef6f85e48..99540807d 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -1,4 +1,6 @@ +#include <nginx.h> + #include <ngx_config.h> #include <ngx_core.h> #include <ngx_types.h> @@ -11,11 +13,12 @@ int ngx_event_accept(ngx_event_t *ev) { - ngx_err_t err; - ngx_socket_t s; - struct sockaddr_in addr; - int addrlen = sizeof(struct sockaddr_in); - ngx_connection_t *cn = (ngx_connection_t *) ev->data; + ngx_err_t err; + ngx_socket_t s; + ngx_event_t *rev, *wev; + ngx_connection_t *c, *ac; + + ac = (ngx_connection_t *) ev->data; ngx_log_debug(ev->log, "ngx_event_accept: accept ready: %d" _ ev->available); @@ -23,69 +26,73 @@ int ngx_event_accept(ngx_event_t *ev) ev->ready = 0; do { - if ((s = accept(cn->fd, cn->sockaddr, &cn->socklen)) == -1) { + if ((s = accept(ac->fd, ac->sockaddr, &ac->socklen)) == -1) { err = ngx_socket_errno; if (err == NGX_EAGAIN) { ngx_log_error(NGX_LOG_INFO, ev->log, err, "ngx_event_accept: EAGAIN while accept %s", - cn->addr_text); + ac->addr_text); return NGX_OK; } ngx_log_error(NGX_LOG_ERR, ev->log, err, - "ngx_event_accept: accept %s failed", cn->addr_text); + "ngx_event_accept: accept %s failed", ac->addr_text); /* if we return NGX_ERROR listen socket would be closed */ return NGX_OK; } - ngx_log_debug(ev->log, "ngx_event_accept: accept: %d" _ s); - #if !(HAVE_INHERITED_NONBLOCK) if (ngx_nonblocking(s) == -1) ngx_log_error(NGX_LOG_ERR, log, ngx_socket_errno, ngx_nonblocking_n "failed"); #endif - ngx_memzero(&ngx_read_events[s], sizeof(ngx_event_t)); - ngx_memzero(&ngx_write_events[s], sizeof(ngx_event_t)); - ngx_memzero(&ngx_connections[s], sizeof(ngx_connection_t)); + rev = &ngx_read_events[s]; + wev = &ngx_write_events[s]; + c = &ngx_connections[s]; + + ngx_memzero(rev, sizeof(ngx_event_t)); + ngx_memzero(wev, sizeof(ngx_event_t)); + ngx_memzero(c, sizeof(ngx_connection_t)); + + c->sockaddr = ac->sockaddr; + c->family = ac->family; + c->socklen = ac->socklen; + c->addr = ac->addr; + c->addr_text.len = ac->addr_text.len; + c->post_accept_timeout = ac->post_accept_timeout; - ngx_connections[s].sockaddr = cn->sockaddr; - ngx_connections[s].family = cn->family; - ngx_connections[s].socklen = cn->socklen; - ngx_connections[s].addr = cn->addr; - ngx_connections[s].addr_text.len = cn->addr_text.len; - ngx_connections[s].post_accept_timeout = cn->post_accept_timeout; + rev->index = wev->index = NGX_INVALID_INDEX; - ngx_read_events[s].data = ngx_write_events[s].data - = &ngx_connections[s]; - ngx_connections[s].read = &ngx_read_events[s]; - ngx_connections[s].write = &ngx_write_events[s]; + rev->data = wev->data = c; + c->read = rev; + c->write = wev; - ngx_connections[s].fd = s; - ngx_connections[s].unexpected_eof = 1; - ngx_write_events[s].write = 1; - ngx_write_events[s].ready = 1; + c->fd = s; + c->unexpected_eof = 1; + wev->write = 1; + wev->ready = 1; - ngx_write_events[s].timer = ngx_read_events[s].timer = 10000; + wev->timer = rev->timer = 10000; + wev->timer_handler = rev->timer_handler = ngx_event_close_connection; + wev->close_handler = rev->close_handler = ngx_event_close_connection; - ngx_write_events[s].timer_handler = - ngx_read_events[s].timer_handler = ngx_event_close_connection; + c->server = ac->server; + c->servers = ac->servers; + c->log = rev->log = wev->log = ev->log; - ngx_write_events[s].close_handler = - ngx_read_events[s].close_handler = ngx_event_close_connection; + /* STUB: x86: SP: xadd, MT: lock xadd, MP: lock xadd, shared */ + c->number = ngx_connection_counter++; - ngx_connections[s].server = cn->server; - ngx_connections[s].servers = cn->servers; - ngx_connections[s].log = - ngx_read_events[s].log = ngx_write_events[s].log = ev->log; + ngx_log_debug(ev->log, "ngx_event_accept: accept: %d, %d" _ + s _ c->number); #if (HAVE_DEFERRED_ACCEPT) if (ev->accept_filter) - ngx_read_events[s].ready = 1; + rev->ready = 1; #endif - cn->handler(&ngx_connections[s]); + ac->handler(c); #if (HAVE_KQUEUE) #if !(USE_KQUEUE) diff --git a/src/event/ngx_event_close.c b/src/event/ngx_event_close.c index 0e3fe20c7..66a3693a7 100644 --- a/src/event/ngx_event_close.c +++ b/src/event/ngx_event_close.c @@ -11,21 +11,20 @@ int ngx_event_close_connection(ngx_event_t *ev) int rc; ngx_connection_t *c = (ngx_connection_t *) ev->data; + ngx_log_debug(c->log, "CLOSE: %d" _ c->fd); + ngx_assert((c->fd != -1), return NGX_ERROR, c->log, "ngx_event_close: already closed"); ngx_destroy_pool(c->pool); + ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); + ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); + if ((rc = ngx_close_socket(c->fd)) == -1) ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, "ngx_event_close: close failed"); - if (c->read->next) - ngx_del_event(c->read, NGX_READ_EVENT); - - if (c->write->next) - ngx_del_event(c->write, NGX_WRITE_EVENT); - c->fd = -1; return rc; diff --git a/src/event/ngx_event_write.c b/src/event/ngx_event_write.c index ccbb1579b..5de80d351 100644 --- a/src/event/ngx_event_write.c +++ b/src/event/ngx_event_write.c @@ -98,8 +98,7 @@ ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in, (ngx_iovec_t *) trailer->elts, trailer->nelts, &sent, c->log); } else { - rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, - header->nelts); + rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, header->nelts); sent = rc > 0 ? rc: 0; |
