Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/event
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-05-19 20:39:14 +0400
committerIgor Sysoev <igor@sysoev.ru>2003-05-19 20:39:14 +0400
commita98301160de4c12f455cca8f78509f2e04626c0b (patch)
treecdf14046298d40ca8398925603fb4011360b187a /src/event
parentbb4ec5c1721defd7b10f83ace51bddb71726dd1a (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.c2
-rw-r--r--src/event/modules/ngx_kqueue_module.c202
-rw-r--r--src/event/modules/ngx_kqueue_module.h19
-rw-r--r--src/event/modules/ngx_poll_module.c5
-rw-r--r--src/event/modules/ngx_select_module.c129
-rw-r--r--src/event/ngx_event.c263
-rw-r--r--src/event/ngx_event.h61
-rw-r--r--src/event/ngx_event_accept.c5
-rw-r--r--src/event/ngx_event_timer.c25
-rw-r--r--src/event/ngx_event_timer.h5
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);