Mercurial > hg > nginx
diff src/event/modules/ngx_kqueue_module.c @ 91:637625a2acdb
nginx-0.0.1-2003-05-19-20:39:14 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 19 May 2003 16:39:14 +0000 |
parents | 37530da31268 |
children | 19cc647ecd91 |
line wrap: on
line diff
--- a/src/event/modules/ngx_kqueue_module.c Fri May 16 15:27:48 2003 +0000 +++ b/src/event/modules/ngx_kqueue_module.c Mon May 19 16:39:14 2003 +0000 @@ -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 @@ 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 @@ }; - -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; + + kcf = ngx_event_get_conf(ngx_kqueue_module_ctx); - nevents = KQUEUE_NEVENTS; +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 + c = ev->data; + ngx_log_error(NGX_LOG_ALERT, ev->log, 0, + "previous event were not passed in kernel", c->fd); - /* if the event is still not passed to a kernel we change it */ - - 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 @@ { #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_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_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 @@ 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 @@ 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 @@ 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 @@ 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; +}