diff options
author | Igor Sysoev <igor@sysoev.ru> | 2003-05-19 20:39:14 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2003-05-19 20:39:14 +0400 |
commit | a98301160de4c12f455cca8f78509f2e04626c0b (patch) | |
tree | cdf14046298d40ca8398925603fb4011360b187a /src/event | |
parent | bb4ec5c1721defd7b10f83ace51bddb71726dd1a (diff) |
nginx-0.0.1-2003-05-19-20:39:14 import
Diffstat (limited to 'src/event')
-rw-r--r-- | src/event/modules/ngx_aio_module.c | 2 | ||||
-rw-r--r-- | src/event/modules/ngx_kqueue_module.c | 202 | ||||
-rw-r--r-- | src/event/modules/ngx_kqueue_module.h | 19 | ||||
-rw-r--r-- | src/event/modules/ngx_poll_module.c | 5 | ||||
-rw-r--r-- | src/event/modules/ngx_select_module.c | 129 | ||||
-rw-r--r-- | src/event/ngx_event.c | 263 | ||||
-rw-r--r-- | src/event/ngx_event.h | 61 | ||||
-rw-r--r-- | src/event/ngx_event_accept.c | 5 | ||||
-rw-r--r-- | src/event/ngx_event_timer.c | 25 | ||||
-rw-r--r-- | src/event/ngx_event_timer.h | 5 |
10 files changed, 471 insertions, 245 deletions
diff --git a/src/event/modules/ngx_aio_module.c b/src/event/modules/ngx_aio_module.c index f2d0e83c7..20cb1a63c 100644 --- a/src/event/modules/ngx_aio_module.c +++ b/src/event/modules/ngx_aio_module.c @@ -21,7 +21,7 @@ int ngx_aio_init(int max_connections, ngx_log_t *log) rc = ngx_kqueue_init(max_connections, log); - ngx_event_flags = NGX_HAVE_AIO_EVENT; + ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_USE_AIO_EVENT; ngx_write_chain_proc = ngx_aio_write_chain; return rc; diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index 8cc7190a1..bf03f5c87 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -1,3 +1,4 @@ + /* * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru */ @@ -5,39 +6,30 @@ #include <ngx_config.h> #include <ngx_core.h> -#include <ngx_types.h> -#include <ngx_log.h> #include <ngx_connection.h> #include <ngx_event.h> -#include <ngx_event_timer.h> -#include <ngx_conf_file.h> #include <ngx_kqueue_module.h> -/* STUB */ -#define KQUEUE_NCHANGES 512 -#define KQUEUE_NEVENTS 512 - +static int ngx_kqueue_init(ngx_log_t *log); +static void ngx_kqueue_done(ngx_log_t *log); +static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags); +static int ngx_kqueue_process_events(ngx_log_t *log); -static int ngx_kqueue_changes; -static int ngx_kqueue_events; +static void *ngx_kqueue_create_conf(ngx_pool_t *pool); +static char *ngx_kqueue_init_conf(ngx_pool_t *pool, void *conf); -/* should be per-thread if threads are used without thread pool */ -#if 1 -int kq; -#else -static int kq; -#endif -static struct kevent *change_list, *event_list; -static unsigned int nchanges; -static int nevents; +int ngx_kqueue; -static ngx_event_t *timer_queue; -/* */ +static struct kevent *change_list, *event_list; +static u_int max_changes, nchanges; +static int nevents; -static ngx_str_t kqueue_name = ngx_string("kqueue"); +static ngx_str_t kqueue_name = ngx_string("kqueue"); static ngx_command_t ngx_kqueue_commands[] = { @@ -45,21 +37,42 @@ static ngx_command_t ngx_kqueue_commands[] = { NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, - addressof(ngx_kqueue_changes), + offsetof(ngx_kqueue_conf_t, changes), NULL}, {ngx_string("kqueue_events"), NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, - addressof(ngx_kqueue_events), + offsetof(ngx_kqueue_conf_t, events), NULL}, {ngx_string(""), 0, NULL, 0, 0, NULL} }; + +ngx_event_module_t ngx_kqueue_module_ctx = { + NGX_EVENT_MODULE, + &kqueue_name, + ngx_kqueue_create_conf, /* create configuration */ + ngx_kqueue_init_conf, /* init configuration */ + + { + ngx_kqueue_add_event, /* add an event */ + ngx_kqueue_del_event, /* delete an event */ + ngx_kqueue_add_event, /* enable an event */ + ngx_kqueue_del_event, /* disable an event */ + NULL, /* add an connection */ + NULL, /* delete an connection */ + ngx_kqueue_process_events, /* process the events */ + ngx_kqueue_init, /* init the events */ + ngx_kqueue_done, /* done the events */ + } + +}; + ngx_module_t ngx_kqueue_module = { - &kqueue_name, /* module context */ + &ngx_kqueue_module_ctx, /* module context */ 0, /* module index */ ngx_kqueue_commands, /* module directives */ NGX_EVENT_MODULE_TYPE, /* module type */ @@ -67,109 +80,91 @@ ngx_module_t ngx_kqueue_module = { }; - -int ngx_kqueue_init(int max_connections, ngx_log_t *log) +static int ngx_kqueue_init(ngx_log_t *log) { - int change_size, event_size; + ngx_kqueue_conf_t *kcf; - nevents = KQUEUE_NEVENTS; + kcf = ngx_event_get_conf(ngx_kqueue_module_ctx); + +ngx_log_debug(log, "CH: %d" _ kcf->changes); +ngx_log_debug(log, "EV: %d" _ kcf->events); + + max_changes = kcf->changes; + nevents = kcf->events; nchanges = 0; - change_size = sizeof(struct kevent) * KQUEUE_NCHANGES; - event_size = sizeof(struct kevent) * KQUEUE_NEVENTS; - kq = kqueue(); + ngx_kqueue = kqueue(); - if (kq == -1) { + if (ngx_kqueue == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "kqueue() failed"); return NGX_ERROR; } - ngx_test_null(change_list, ngx_alloc(change_size, log), NGX_ERROR); - ngx_test_null(event_list, ngx_alloc(event_size, log), NGX_ERROR); + ngx_test_null(change_list, + ngx_alloc(kcf->changes * sizeof(struct kevent), log), + NGX_ERROR); + ngx_test_null(event_list, + ngx_alloc(kcf->events * sizeof(struct kevent), log), + NGX_ERROR); - timer_queue = ngx_event_init_timer(log); - if (timer_queue == NULL) { + if (ngx_event_timer_init(log) == NGX_ERROR) { return NGX_ERROR; } - ngx_event_actions.add = ngx_kqueue_add_event; - ngx_event_actions.del = ngx_kqueue_del_event; - ngx_event_actions.timer = ngx_event_add_timer; - ngx_event_actions.process = ngx_kqueue_process_events; - -#if (HAVE_AIO_EVENT) - - ngx_event_flags = NGX_HAVE_AIO_EVENT; - -#else + ngx_event_actions = ngx_kqueue_module_ctx.actions; ngx_event_flags = NGX_HAVE_LEVEL_EVENT |NGX_HAVE_ONESHOT_EVENT - #if (HAVE_CLEAR_EVENT) |NGX_HAVE_CLEAR_EVENT #else |NGX_USE_LEVEL_EVENT #endif - #if (HAVE_LOWAT_EVENT) |NGX_HAVE_LOWAT_EVENT #endif - |NGX_HAVE_KQUEUE_EVENT; - ngx_write_chain_proc = ngx_freebsd_write_chain; - -#endif - return NGX_OK; } -void ngx_kqueue_done(ngx_log_t *log) +static void ngx_kqueue_done(ngx_log_t *log) { - if (close(kq) == -1) { + if (close(ngx_kqueue) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "kqueue close() failed"); } + + ngx_event_timer_done(log); + + ngx_free(change_list); + ngx_free(event_list); } -int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) +static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) { + ngx_connection_t *c; + ev->active = 1; ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; - /* The event addition or change should be always passed to a kernel - because there can be case when event was passed to a kernel then - added again to the change_list and then deleted from the change_list - by ngx_kqueue_del_event() so the first event still remains in a kernel */ - -#if 0 - if (nchanges > 0 && ev->index < nchanges - && change_list[ev->index].udata == ev) + && (void *) ((uintptr_t) change_list[ev->index].udata & ~1) == ev) { -#if (NGX_DEBUG_EVENT) - ngx_connection_t *c = (ngx_connection_t *) ev->data; - ngx_log_debug(ev->log, "kqueue add event: %d: ft:%d" _ c->fd _ event); -#endif - - /* if the event is still not passed to a kernel we change it */ + c = ev->data; + ngx_log_error(NGX_LOG_ALERT, ev->log, 0, + "previous event were not passed in kernel", c->fd); - change_list[ev->index].filter = event; - change_list[ev->index].flags = flags; - - return NGX_OK; + return NGX_ERROR; } -#endif - return ngx_kqueue_set_event(ev, event, EV_ADD | flags); } -int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) +static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) { ngx_event_t *e; @@ -181,7 +176,8 @@ int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) { #if (NGX_DEBUG_EVENT) ngx_connection_t *c = (ngx_connection_t *) ev->data; - ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _ c->fd _ event); + ngx_log_debug(ev->log, "kqueue event deleted: %d: ft:%d" _ + c->fd _ event); #endif /* if the event is still not passed to a kernel we will not pass it */ @@ -207,26 +203,26 @@ 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) +static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags) { - struct timespec ts; - ngx_connection_t *c; + struct timespec ts; + ngx_connection_t *c; - c = (ngx_connection_t *) ev->data; + c = ev->data; #if (NGX_DEBUG_EVENT) ngx_log_debug(ev->log, "kqueue set event: %d: ft:%d f:%08x" _ c->fd _ filter _ flags); #endif - if (nchanges >= KQUEUE_NCHANGES) { + if (nchanges >= max_changes) { ngx_log_error(NGX_LOG_WARN, ev->log, 0, "kqueue change list is filled up"); ts.tv_sec = 0; ts.tv_nsec = 0; - if (kevent(kq, change_list, nchanges, NULL, 0, &ts) == -1) { + if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent failed"); return NGX_ERROR; } @@ -265,7 +261,7 @@ int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags) } -int ngx_kqueue_process_events(ngx_log_t *log) +static int ngx_kqueue_process_events(ngx_log_t *log) { int events, instance, i; ngx_msec_t timer, delta; @@ -292,7 +288,7 @@ int ngx_kqueue_process_events(ngx_log_t *log) ngx_log_debug(log, "kevent timer: %d" _ timer); #endif - events = kevent(kq, change_list, nchanges, event_list, nevents, tp); + events = kevent(ngx_kqueue, change_list, nchanges, event_list, nevents, tp); if (events == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "kevent failed"); @@ -305,8 +301,8 @@ int ngx_kqueue_process_events(ngx_log_t *log) gettimeofday(&tv, NULL); delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; - /* Expired timers must be deleted before the events processing - because the new timers can be added during the processing */ + /* The expired timers must be handled before a processing of the events + because the new timers can be added during a processing */ ngx_event_expire_timers(delta); @@ -370,8 +366,9 @@ int ngx_kqueue_process_events(ngx_log_t *log) ev->error = event_list[i].fflags; } - if (ev->oneshot) { + if (ev->oneshot && ev->timer_set) { ngx_del_timer(ev); + ev->timer_set = 0; } /* fall through */ @@ -392,3 +389,28 @@ int ngx_kqueue_process_events(ngx_log_t *log) return NGX_OK; } + + +static void *ngx_kqueue_create_conf(ngx_pool_t *pool) +{ + ngx_kqueue_conf_t *kcf; + + ngx_test_null(kcf, ngx_palloc(pool, sizeof(ngx_kqueue_conf_t)), + NGX_CONF_ERROR); + + kcf->changes = NGX_CONF_UNSET; + kcf->events = NGX_CONF_UNSET; + + return kcf; +} + + +static char *ngx_kqueue_init_conf(ngx_pool_t *pool, void *conf) +{ + ngx_kqueue_conf_t *kcf = conf; + + ngx_conf_init_value(kcf->changes, 512); + ngx_conf_init_value(kcf->events, 512); + + return NGX_CONF_OK; +} diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h index 568476ed0..4f41ae790 100644 --- a/src/event/modules/ngx_kqueue_module.h +++ b/src/event/modules/ngx_kqueue_module.h @@ -2,22 +2,13 @@ #define _NGX_KQUEUE_MODULE_H_INCLUDED_ -#include <ngx_types.h> -#include <ngx_log.h> -#include <ngx_event.h> +typedef struct { + int changes; + int events; +} ngx_kqueue_conf_t; -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, 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); - - -#if 1 -extern int kq; -#endif +extern int ngx_kqueue; #endif /* _NGX_KQUEUE_MODULE_H_INCLUDED_ */ diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c index f0f39ddbc..c58c898e4 100644 --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -242,7 +242,10 @@ int ngx_poll_process_events(ngx_log_t *log) ev->ready = 1; if (ev->oneshot) { - ngx_del_timer(ev); + if (ev->timer_set) { + ngx_del_timer(ev); + ev->timer_set = 0; + } if (ev->write) { ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0); diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c index 74c790e52..bb3c89d29 100644 --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -1,16 +1,24 @@ +/* + * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru + */ + + #include <ngx_config.h> #include <ngx_core.h> -#include <ngx_types.h> -#include <ngx_log.h> -#include <ngx_time.h> #include <ngx_connection.h> #include <ngx_event.h> -#include <ngx_event_timer.h> -#include <ngx_select_module.h> -/* should be per-thread */ +static int ngx_select_init(ngx_log_t *log); +static void ngx_select_done(ngx_log_t *log); +static int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_select_process_events(ngx_log_t *log); + +static char *ngx_select_init_conf(ngx_pool_t *pool, void *conf); + + static fd_set master_read_fd_set; static fd_set master_write_fd_set; static fd_set work_read_fd_set; @@ -27,45 +35,67 @@ static u_int nevents; static ngx_event_t **event_index; static ngx_event_t **ready_index; -static ngx_event_t *timer_queue; -/* */ -int ngx_select_init(int max_connections, ngx_log_t *log) -{ - if (max_connections > FD_SETSIZE) { - ngx_log_error(NGX_LOG_EMERG, log, 0, -#if (WIN32) - "maximum number of descriptors " - "supported by select() is %d", FD_SETSIZE); -#else - "maximum descriptor number" - "supported by select() is %d", FD_SETSIZE - 1); -#endif - exit(1); + +static ngx_str_t select_name = ngx_string("select"); + +ngx_event_module_t ngx_select_module_ctx = { + NGX_EVENT_MODULE, + &select_name, + NULL, /* create configuration */ + ngx_select_init_conf, /* init configuration */ + + { + ngx_select_add_event, /* add an event */ + ngx_select_del_event, /* delete an event */ + ngx_select_add_event, /* enable an event */ + ngx_select_del_event, /* disable an event */ + NULL, /* add an connection */ + NULL, /* delete an connection */ + ngx_select_process_events, /* process the events */ + ngx_select_init, /* init the events */ + ngx_select_done /* done the events */ } +}; + +ngx_module_t ngx_select_module = { + &ngx_select_module_ctx, /* module context */ + 0, /* module index */ + NULL, /* module directives */ + NGX_EVENT_MODULE_TYPE, /* module type */ + NULL /* init module */ +}; + + +static int ngx_select_init(ngx_log_t *log) +{ + ngx_event_conf_t *ecf; + + ecf = ngx_event_get_conf(ngx_event_module_ctx); + FD_ZERO(&master_read_fd_set); FD_ZERO(&master_write_fd_set); ngx_test_null(event_index, - ngx_alloc(sizeof(ngx_event_t *) * 2 * max_connections, log), + ngx_alloc(sizeof(ngx_event_t *) * 2 * ecf->connections, log), NGX_ERROR); ngx_test_null(ready_index, - ngx_alloc(sizeof(ngx_event_t *) * 2 * max_connections, log), + ngx_alloc(sizeof(ngx_event_t *) * 2 * ecf->connections, log), NGX_ERROR); nevents = 0; - timer_queue = ngx_event_init_timer(log); - if (timer_queue == NULL) { + if (ngx_event_timer_init(log) == NGX_ERROR) { return NGX_ERROR; } - ngx_event_actions.add = ngx_select_add_event; - ngx_event_actions.del = ngx_select_del_event; - ngx_event_actions.timer = ngx_event_add_timer; - ngx_event_actions.process = ngx_select_process_events; + ngx_event_actions = ngx_select_module_ctx.actions; + + ngx_event_flags = NGX_HAVE_LEVEL_EVENT + |NGX_HAVE_ONESHOT_EVENT + |NGX_USE_LEVEL_EVENT; #if (WIN32) max_read = max_write = 0; @@ -76,11 +106,19 @@ int ngx_select_init(int max_connections, ngx_log_t *log) return NGX_OK; } -int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) + +static void ngx_select_done(ngx_log_t *log) +{ + ngx_free(event_index); + ngx_free(ready_index); +} + + +static int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) { ngx_connection_t *c; - c = (ngx_connection_t *) ev->data; + c = ev->data; #if (NGX_DEBUG_EVENT) ngx_log_debug(ev->log, "select fd:%d event:%d" _ c->fd _ event); @@ -132,10 +170,12 @@ 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, u_int flags) + +static 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_connection_t *c; + + c = ev->data; if (ev->index == NGX_INVALID_INDEX) return NGX_OK; @@ -175,7 +215,8 @@ int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags) return NGX_OK; } -int ngx_select_process_events(ngx_log_t *log) + +static int ngx_select_process_events(ngx_log_t *log) { int ready, found; u_int i, nready; @@ -298,7 +339,10 @@ int ngx_select_process_events(ngx_log_t *log) ev->ready = 1; if (ev->oneshot) { - ngx_del_timer(ev); + if (ev->timer_set) { + ngx_del_timer(ev); + ev->timer_set = 0; + } if (ev->write) ngx_select_del_event(ev, NGX_WRITE_EVENT, 0); @@ -315,3 +359,18 @@ int ngx_select_process_events(ngx_log_t *log) return NGX_OK; } + + +static char *ngx_select_init_conf(ngx_pool_t *pool, void *conf) +{ + ngx_event_conf_t *ecf; + + ecf = ngx_event_get_conf(ngx_event_module_ctx); + + if (ecf->connections > FD_SETSIZE) { + return "maximum number of connections " + "supported by select() is " ngx_value(FD_SETSIZE); + } + + return NGX_CONF_OK; +} diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index a3b12d0f6..ed22db5c6 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -11,7 +11,7 @@ #include <ngx_event.h> #include <ngx_conf_file.h> -#include <ngx_select_module.h> +extern ngx_event_module_t ngx_select_module_ctx; #if (HAVE_POLL) #include <ngx_poll_module.h> @@ -22,6 +22,7 @@ #endif #if (HAVE_KQUEUE) +extern ngx_event_module_t ngx_kqueue_module_ctx; #include <ngx_kqueue_module.h> #endif @@ -36,46 +37,26 @@ static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); +static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); +static void *ngx_event_create_conf(ngx_pool_t *pool); +static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf); -ngx_connection_t *ngx_connections; -ngx_event_t *ngx_read_events, *ngx_write_events; - -#if !(USE_KQUEUE) - -ngx_event_type_e ngx_event_type; - int ngx_event_flags; - ngx_event_actions_t ngx_event_actions; -/* ngx_event_type_e order */ -static int (*ngx_event_init[]) (int max_connections, ngx_log_t *log) = { - ngx_select_init, -#if (HAVE_POLL) - ngx_poll_init, -#endif -#if (HAVE_DEVPOLL) - ngx_devpoll_init, -#endif -#if (HAVE_KQUEUE) - ngx_kqueue_init, -#endif -#if (HAVE_AIO) - ngx_aio_init, -#endif -#if (HAVE_IOCP) - ngx_iocp_init -#endif -}; +ngx_connection_t *ngx_connections; +ngx_event_t *ngx_read_events, *ngx_write_events; + -#endif /* USE_KQUEUE */ +static int ngx_event_max_module; static int ngx_event_connections; static ngx_str_t events_name = ngx_string("events"); +static ngx_str_t event_name = ngx_string("event"); static ngx_command_t ngx_events_commands[] = { @@ -106,67 +87,87 @@ static ngx_command_t ngx_event_commands[] = { NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, - addressof(ngx_event_connections), + offsetof(ngx_event_conf_t, connections), NULL}, -#if 0 {ngx_string("type"), NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_event_set_type, 0, 0, NULL}, -#endif + + {ngx_string("timer_queues"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_event_conf_t, timer_queues), + NULL}, {ngx_string(""), 0, NULL, 0, 0, NULL} }; +ngx_event_module_t ngx_event_module_ctx = { + NGX_EVENT_MODULE, + &event_name, + ngx_event_create_conf, /* create configuration */ + ngx_event_init_conf, /* init configuration */ + + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + + ngx_module_t ngx_event_module = { - NULL, /* module context */ + &ngx_event_module_ctx, /* module context */ 0, /* module index */ - ngx_events_commands, /* module directives */ + ngx_event_commands, /* module directives */ NGX_EVENT_MODULE_TYPE, /* module type */ NULL /* init module */ }; -void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) +int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) { - int i, fd; + int m, i, fd; ngx_listen_t *s; ngx_event_t *ev; ngx_connection_t *c; + ngx_event_conf_t *ecf; + ngx_event_module_t *module; - /* STUB */ - int max_connections = 512; + ecf = ngx_event_get_conf(ngx_event_module_ctx); -#if 0 - ngx_event_type = NGX_POLL_EVENT_N; -#endif -#if 1 - ngx_event_type = NGX_KQUEUE_EVENT_N; -#endif -#if 0 - ngx_event_type = NGX_DEVPOLL_EVENT_N; -#endif -#if 0 - ngx_event_type = NGX_AIO_EVENT_N; -#endif -#if 0 - ngx_event_type = NGX_IOCP_EVENT_N; -#endif +ngx_log_debug(log, "CONN: %d" _ ecf->connections); +ngx_log_debug(log, "TYPE: %d" _ ecf->type); - if (ngx_init_events(max_connections, log) == NGX_ERROR) { - exit(1); + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } + + module = ngx_modules[m]->ctx; + if (module->index == ecf->type) { + if (module->actions.init(log) == NGX_ERROR) { + return NGX_ERROR; + } + break; + } } - ngx_connections = ngx_alloc(sizeof(ngx_connection_t) - * max_connections, log); - ngx_read_events = ngx_alloc(sizeof(ngx_event_t) * max_connections, log); - ngx_write_events = ngx_alloc(sizeof(ngx_event_t) * max_connections, log); + ngx_test_null(ngx_connections, + ngx_alloc(sizeof(ngx_connection_t) * ecf->connections, log), + NGX_ERROR); + + ngx_test_null(ngx_read_events, + ngx_alloc(sizeof(ngx_event_t) * ecf->connections, log), + NGX_ERROR); + + ngx_test_null(ngx_write_events, + ngx_alloc(sizeof(ngx_event_t) * ecf->connections, log), + NGX_ERROR); /* for each listening socket */ s = (ngx_listen_t *) ls->elts; @@ -196,7 +197,9 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) c->pool_size = s[i].pool_size; ngx_test_null(ev->log, - ngx_palloc(pool, sizeof(ngx_log_t)), /* void */ ; ); + ngx_palloc(pool, sizeof(ngx_log_t)), + NGX_ERROR); + ngx_memcpy(ev->log, c->log, sizeof(ngx_log_t)); c->read = ev; ev->data = c; @@ -235,6 +238,8 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) #endif } + + return NGX_OK; } @@ -248,35 +253,50 @@ void ngx_worker(ngx_log_t *log) } -static char *ngx_events_init(ngx_pool_t *pool) +static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { - ngx_event_connections = -1; - ngx_event_type = -1; + int m; + char *rv; + void ***ctx; + ngx_conf_t pcf; + ngx_event_conf_t *ecf; + ngx_event_module_t *module; + + /* count the number of the event modules and set up their indices */ + + ngx_event_max_module = 0; + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } - return NGX_CONF_OK; -} + module = ngx_modules[m]->ctx; + module->index = ngx_event_max_module++; + } + ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(void *)), NGX_CONF_ERROR); -static char *ngx_events_postconf(ngx_pool_t *pool) -{ - if (ngx_event_connections == -1) { - ngx_event_connections = 512; - } + ngx_test_null(*ctx, + ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *)), + NGX_CONF_ERROR); - return NGX_CONF_OK; -} + *(void **) conf = ctx; + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } -static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) -{ - char *rv; - ngx_conf_t pcf; + module = ngx_modules[m]->ctx; -#if 0 - *(ngx_events_conf_ctx_t **) conf = ctx; -#endif + if (module->create_conf) { + ngx_test_null((*ctx)[module->index], module->create_conf(cf->pool), + NGX_CONF_ERROR); + } + } pcf = *cf; + cf->ctx = ctx; cf->module_type = NGX_EVENT_MODULE_TYPE; cf->cmd_type = NGX_EVENT_CONF; rv = ngx_conf_parse(cf, NULL); @@ -285,5 +305,90 @@ static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) if (rv != NGX_CONF_OK) return rv; + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } + + module = ngx_modules[m]->ctx; + + if (module->init_conf) { + rv = module->init_conf(cf->pool, (*ctx)[module->index]); + if (rv != NGX_CONF_OK) { + return rv; + } + } + } + + return NGX_CONF_OK; +} + + +static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +{ + ngx_event_conf_t *ecf = (ngx_event_conf_t *) conf; + + int m; + ngx_str_t *args; + ngx_event_module_t *module; + + if (ecf->type != NGX_CONF_UNSET) { + return "duplicate event type" ; + } + + args = cf->args->elts; + + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } + + module = ngx_modules[m]->ctx; + if (module->name->len == args[1].len) { + if (ngx_strcmp(module->name->data, args[1].data) == 0) { + ecf->type = module->index; + return NGX_CONF_OK; + } + } + } + + return "invalid event type"; +} + + +static void *ngx_event_create_conf(ngx_pool_t *pool) +{ + ngx_event_conf_t *ecf; + + ngx_test_null(ecf, ngx_palloc(pool, sizeof(ngx_event_conf_t)), + NGX_CONF_ERROR); + + ecf->connections = NGX_CONF_UNSET; + ecf->type = NGX_CONF_UNSET; + + return ecf; +} + + +static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf) +{ + ngx_event_conf_t *ecf = conf; + +#if (HAVE_KQUEUE) + + ngx_conf_init_value(ecf->connections, 1024); + ngx_conf_init_value(ecf->type, ngx_kqueue_module_ctx.index); + +#else /* HAVE_SELECT */ + + ngx_conf_init_value(ecf->connections, + FD_SETSIZE < 1024 ? FD_SETSIZE : 1024); + + ngx_conf_init_value(ecf->type, ngx_select_module_ctx.index); + +#endif + + ngx_conf_init_value(ecf->timer_queues, 10); + return NGX_CONF_OK; } diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index c976e17a5..3b189d631 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -9,12 +9,16 @@ #include <ngx_log.h> #include <ngx_alloc.h> #include <ngx_array.h> +#include <ngx_conf_file.h> + + /* STUB */ #define NGX_LOWAT 10000 #define NGX_INVALID_INDEX 0x80000000 + typedef struct ngx_event_s ngx_event_t; #if (HAVE_IOCP) @@ -141,15 +145,21 @@ typedef enum { NGX_DUMMY_EVENT_N /* avoid comma at end of enumerator list */ } ngx_event_type_e ; + + typedef struct { - int (*add)(ngx_event_t *ev, int event, u_int flags); - 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); -/* - int (*write)(ngx_event_t *ev, char *buf, size_t size); -*/ + int (*add)(ngx_event_t *ev, int event, u_int flags); + int (*del)(ngx_event_t *ev, int event, u_int flags); + + int (*enable)(ngx_event_t *ev, int event, u_int flags); + int (*disable)(ngx_event_t *ev, int event, u_int flags); + + int (*add_conn)(ngx_connection_t *c); + int (*del_conn)(ngx_connection_t *c); + + int (*process)(ngx_log_t *log); + int (*init)(ngx_log_t *log); + void (*done)(ngx_log_t *log); } ngx_event_actions_t; @@ -273,7 +283,8 @@ typedef struct { #elif (HAVE_AIO_EVENT) #define ngx_event_recv ngx_event_aio_read #else -#define ngx_event_recv ngx_event_recv_core +#define ngx_event_recv ngx_io.recv +#define ngx_write_chain ngx_io.send_chain #endif #endif @@ -301,6 +312,33 @@ extern int ngx_event_flags; #define NGX_EVENT_MODULE_TYPE 0x544E5645 /* "EVNT" */ #define NGX_EVENT_CONF 0x00200000 +#define NGX_EVENT_MODULE 0 + + +typedef struct { + int connections; + int type; + int timer_queues; +} ngx_event_conf_t; + + +typedef struct { + int index; + ngx_str_t *name; + + void *(*create_conf)(ngx_pool_t *p); + char *(*init_conf)(ngx_pool_t *p, void *conf); + + ngx_event_actions_t actions; +} ngx_event_module_t; + + +extern ngx_module_t ngx_events_module; +extern ngx_event_module_t ngx_event_module_ctx; + + +#define ngx_event_get_conf(module) \ + (*(ngx_get_conf(ngx_events_module))) [module.index]; @@ -311,8 +349,11 @@ ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size); int ngx_event_close_connection(ngx_event_t *ev); -void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log); +int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log); void ngx_worker(ngx_log_t *log); +#include <ngx_event_timer.h> + + #endif /* _NGX_EVENT_H_INCLUDED_ */ diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 26bc2e3cf..720b3a53b 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -175,10 +175,7 @@ void ngx_event_accept(ngx_event_t *ev) #elif (HAVE_KQUEUE) -/* - if (ngx_event_type == NGX_HAVE_AIO_EVENT or NGX_HAVE_KQUEUE_EVENT) { -*/ - if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT) { + if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { ev->available--; } diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c index b5dfdf9ef..03e29d9c4 100644 --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -9,33 +9,38 @@ #include <ngx_event_timer.h> -/* STUB */ -#define NGX_TIMER_QUEUE_NUM 5 -/* should be per-thread */ static ngx_event_t *ngx_timer_queue; static int ngx_timer_cur_queue; -/* */ static int ngx_timer_queue_num; -ngx_event_t *ngx_event_init_timer(ngx_log_t *log) +int ngx_event_timer_init(ngx_log_t *log) { - int i; + int i; + ngx_event_conf_t *ecf; - ngx_timer_queue_num = NGX_TIMER_QUEUE_NUM; + ecf = ngx_event_get_conf(ngx_event_module_ctx); + + ngx_timer_queue_num = ecf->timer_queues; ngx_timer_cur_queue = 0; ngx_test_null(ngx_timer_queue, ngx_alloc(ngx_timer_queue_num * sizeof(ngx_event_t), log), - NULL); + NGX_ERROR); for (i = 0; i < ngx_timer_queue_num; i++) { ngx_timer_queue[i].timer_prev = &ngx_timer_queue[i]; ngx_timer_queue[i].timer_next = &ngx_timer_queue[i]; } - return ngx_timer_queue; + return NGX_OK;; +} + + +void ngx_event_timer_done(ngx_log_t *log) +{ + ngx_free(ngx_timer_queue); } @@ -126,6 +131,8 @@ void ngx_event_expire_timers(ngx_msec_t timer) delta -= ev->timer_delta; ngx_del_timer(ev); + ev->timer_set = 0; + if (ev->delayed) { ev->delayed = 0; if (ev->ready == 0) { diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h index f5f78ae95..cb024a38f 100644 --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -9,9 +9,10 @@ #include <ngx_event.h> -ngx_event_t *ngx_event_init_timer(ngx_log_t *log); +int ngx_event_timer_init(ngx_log_t *log); +void ngx_event_timer_done(ngx_log_t *log); void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer); -int ngx_event_find_timer(void); +int ngx_event_find_timer(void); void ngx_event_expire_timers(ngx_msec_t timer); |