blob: bdd1ff4c3887522310ddb4a81827622ead1930a9 [file] [log] [blame]
Igor Sysoeva9830112003-05-19 16:39:14 +00001
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00002/*
Igor Sysoev6a644c62003-03-04 06:33:48 +00003 * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00004 */
5
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00006
7#include <ngx_config.h>
Igor Sysoev016b8522002-08-29 16:59:54 +00008#include <ngx_core.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00009#include <ngx_event.h>
10#include <ngx_kqueue_module.h>
11
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000012
Igor Sysoeve4a25262003-06-06 14:59:20 +000013typedef struct {
Igor Sysoev7349bef2003-07-03 16:30:22 +000014 u_int changes;
Igor Sysoev7349bef2003-07-03 16:30:22 +000015 u_int events;
Igor Sysoeve4a25262003-06-06 14:59:20 +000016} ngx_kqueue_conf_t;
17
18
Igor Sysoev340b03b2003-07-04 15:10:33 +000019static int ngx_kqueue_init(ngx_cycle_t *cycle);
20static void ngx_kqueue_done(ngx_cycle_t *cycle);
Igor Sysoeva9830112003-05-19 16:39:14 +000021static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags);
22static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags);
23static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags);
24static int ngx_kqueue_process_events(ngx_log_t *log);
25
26static void *ngx_kqueue_create_conf(ngx_pool_t *pool);
27static char *ngx_kqueue_init_conf(ngx_pool_t *pool, void *conf);
Igor Sysoev3a17f242002-12-24 17:30:59 +000028
29
Igor Sysoevbe2cfc32003-06-15 18:32:13 +000030int ngx_kqueue = -1;
Igor Sysoeva9830112003-05-19 16:39:14 +000031
32static struct kevent *change_list, *event_list;
Igor Sysoevbe2cfc32003-06-15 18:32:13 +000033static u_int max_changes, nchanges, nevents;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000034
35
Igor Sysoeva9830112003-05-19 16:39:14 +000036static ngx_str_t kqueue_name = ngx_string("kqueue");
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000037
38static ngx_command_t ngx_kqueue_commands[] = {
39
40 {ngx_string("kqueue_changes"),
41 NGX_EVENT_CONF|NGX_CONF_TAKE1,
42 ngx_conf_set_num_slot,
43 0,
Igor Sysoeva9830112003-05-19 16:39:14 +000044 offsetof(ngx_kqueue_conf_t, changes),
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000045 NULL},
46
47 {ngx_string("kqueue_events"),
48 NGX_EVENT_CONF|NGX_CONF_TAKE1,
49 ngx_conf_set_num_slot,
50 0,
Igor Sysoeva9830112003-05-19 16:39:14 +000051 offsetof(ngx_kqueue_conf_t, events),
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000052 NULL},
53
Igor Sysoev6253ca12003-05-27 12:18:54 +000054 ngx_null_command
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000055};
56
Igor Sysoeva9830112003-05-19 16:39:14 +000057
58ngx_event_module_t ngx_kqueue_module_ctx = {
Igor Sysoeva9830112003-05-19 16:39:14 +000059 &kqueue_name,
60 ngx_kqueue_create_conf, /* create configuration */
61 ngx_kqueue_init_conf, /* init configuration */
62
Igor Sysoev187fcd82003-05-23 11:53:01 +000063 {
Igor Sysoeva9830112003-05-19 16:39:14 +000064 ngx_kqueue_add_event, /* add an event */
65 ngx_kqueue_del_event, /* delete an event */
66 ngx_kqueue_add_event, /* enable an event */
67 ngx_kqueue_del_event, /* disable an event */
68 NULL, /* add an connection */
69 NULL, /* delete an connection */
70 ngx_kqueue_process_events, /* process the events */
71 ngx_kqueue_init, /* init the events */
Igor Sysoevfa73aac2003-05-21 13:28:21 +000072 ngx_kqueue_done /* done the events */
Igor Sysoeva9830112003-05-19 16:39:14 +000073 }
74
75};
76
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000077ngx_module_t ngx_kqueue_module = {
Igor Sysoev6253ca12003-05-27 12:18:54 +000078 NGX_MODULE,
Igor Sysoeva9830112003-05-19 16:39:14 +000079 &ngx_kqueue_module_ctx, /* module context */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000080 ngx_kqueue_commands, /* module directives */
Igor Sysoev6253ca12003-05-27 12:18:54 +000081 NGX_EVENT_MODULE, /* module type */
Igor Sysoevbe3c2b62003-07-04 06:03:52 +000082 NULL, /* init module */
Igor Sysoevbe3c2b62003-07-04 06:03:52 +000083 NULL /* init child */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000084};
85
86
Igor Sysoev7349bef2003-07-03 16:30:22 +000087
Igor Sysoev340b03b2003-07-04 15:10:33 +000088static int ngx_kqueue_init(ngx_cycle_t *cycle)
Igor Sysoev7349bef2003-07-03 16:30:22 +000089{
90 struct timespec ts;
91 ngx_kqueue_conf_t *kcf;
92
93 kcf = ngx_event_get_conf(cycle->conf_ctx, ngx_kqueue_module);
94
Igor Sysoev340b03b2003-07-04 15:10:33 +000095ngx_log_debug(cycle->log, "CH: %d" _ kcf->changes);
96ngx_log_debug(cycle->log, "EV: %d" _ kcf->events);
Igor Sysoeva9830112003-05-19 16:39:14 +000097
Igor Sysoeva9830112003-05-19 16:39:14 +000098 if (ngx_kqueue == -1) {
Igor Sysoevbe2cfc32003-06-15 18:32:13 +000099 ngx_kqueue = kqueue();
100
101 if (ngx_kqueue == -1) {
Igor Sysoev340b03b2003-07-04 15:10:33 +0000102 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
103 "kqueue() failed");
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000104 return NGX_ERROR;
105 }
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000106 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000107
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000108 if (max_changes < kcf->changes) {
109 if (nchanges) {
110 ts.tv_sec = 0;
111 ts.tv_nsec = 0;
112
113 if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) {
Igor Sysoev340b03b2003-07-04 15:10:33 +0000114 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
115 "kevent() failed");
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000116 return NGX_ERROR;
117 }
Igor Sysoev340b03b2003-07-04 15:10:33 +0000118 nchanges = 0;
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000119 }
120
121 if (change_list) {
122 ngx_free(change_list);
123 }
124
125 ngx_test_null(change_list,
Igor Sysoev340b03b2003-07-04 15:10:33 +0000126 ngx_alloc(kcf->changes * sizeof(struct kevent),
127 cycle->log),
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000128 NGX_ERROR);
129 }
130
131 max_changes = kcf->changes;
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000132
133 if (nevents < kcf->events) {
134 if (event_list) {
135 ngx_free(event_list);
136 }
137
138 ngx_test_null(event_list,
Igor Sysoev340b03b2003-07-04 15:10:33 +0000139 ngx_alloc(kcf->events * sizeof(struct kevent),
140 cycle->log),
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000141 NGX_ERROR);
142 }
143
144 nevents = kcf->events;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000145
Igor Sysoev340b03b2003-07-04 15:10:33 +0000146 if (ngx_event_timer_init(cycle) == NGX_ERROR) {
Igor Sysoevfcce8d52003-01-23 18:47:54 +0000147 return NGX_ERROR;
148 }
149
Igor Sysoev340b03b2003-07-04 15:10:33 +0000150 ngx_io = ngx_os_io;
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000151
Igor Sysoeva9830112003-05-19 16:39:14 +0000152 ngx_event_actions = ngx_kqueue_module_ctx.actions;
Igor Sysoev1e7ec9d2003-02-11 07:14:40 +0000153
Igor Sysoev9b25d692003-01-26 21:08:14 +0000154 ngx_event_flags = NGX_HAVE_LEVEL_EVENT
Igor Sysoev73009772003-02-06 17:21:13 +0000155 |NGX_HAVE_ONESHOT_EVENT
Igor Sysoev1e7ec9d2003-02-11 07:14:40 +0000156#if (HAVE_CLEAR_EVENT)
157 |NGX_HAVE_CLEAR_EVENT
Igor Sysoevb7387572003-03-11 20:38:13 +0000158#else
159 |NGX_USE_LEVEL_EVENT
Igor Sysoev73009772003-02-06 17:21:13 +0000160#endif
Igor Sysoev6a644c62003-03-04 06:33:48 +0000161#if (HAVE_LOWAT_EVENT)
162 |NGX_HAVE_LOWAT_EVENT
163#endif
Igor Sysoev1e7ec9d2003-02-11 07:14:40 +0000164 |NGX_HAVE_KQUEUE_EVENT;
165
Igor Sysoev31f88182002-09-27 15:05:29 +0000166 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000167}
168
Igor Sysoev42feecb2002-12-15 06:25:09 +0000169
Igor Sysoev340b03b2003-07-04 15:10:33 +0000170static void ngx_kqueue_done(ngx_cycle_t *cycle)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000171{
Igor Sysoeva9830112003-05-19 16:39:14 +0000172 if (close(ngx_kqueue) == -1) {
Igor Sysoev340b03b2003-07-04 15:10:33 +0000173 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
174 "kqueue close() failed");
Igor Sysoev6a644c62003-03-04 06:33:48 +0000175 }
Igor Sysoeva9830112003-05-19 16:39:14 +0000176
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000177 ngx_kqueue = -1;
178
Igor Sysoev340b03b2003-07-04 15:10:33 +0000179 ngx_event_timer_done(cycle);
Igor Sysoeva9830112003-05-19 16:39:14 +0000180
181 ngx_free(change_list);
182 ngx_free(event_list);
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000183
184 change_list = NULL;
185 event_list = NULL;
186 max_changes = 0;
187 nchanges = 0;
188 nevents = 0;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000189}
190
191
Igor Sysoeva9830112003-05-19 16:39:14 +0000192static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000193{
Igor Sysoeva9830112003-05-19 16:39:14 +0000194 ngx_connection_t *c;
195
Igor Sysoev3a17f242002-12-24 17:30:59 +0000196 ev->active = 1;
Igor Sysoev1c13c662003-05-20 15:37:55 +0000197 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0;
Igor Sysoev3a40d482002-09-12 14:42:29 +0000198
Igor Sysoeva6717c42002-12-23 06:29:22 +0000199 if (nchanges > 0
200 && ev->index < nchanges
Igor Sysoeva9830112003-05-19 16:39:14 +0000201 && (void *) ((uintptr_t) change_list[ev->index].udata & ~1) == ev)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000202 {
Igor Sysoeva9830112003-05-19 16:39:14 +0000203 c = ev->data;
204 ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
205 "previous event were not passed in kernel", c->fd);
Igor Sysoevdc479b42003-03-20 16:09:44 +0000206
Igor Sysoeva9830112003-05-19 16:39:14 +0000207 return NGX_ERROR;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000208 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000209
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000210 return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
211}
212
Igor Sysoev42feecb2002-12-15 06:25:09 +0000213
Igor Sysoeva9830112003-05-19 16:39:14 +0000214static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000215{
Igor Sysoev3a17f242002-12-24 17:30:59 +0000216 ngx_event_t *e;
217
218 ev->active = 0;
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000219
Igor Sysoeva6717c42002-12-23 06:29:22 +0000220 if (nchanges > 0
221 && ev->index < nchanges
Igor Sysoev6b863e32003-05-12 15:52:24 +0000222 && (void *) ((uintptr_t) change_list[ev->index].udata & ~1) == ev)
Igor Sysoev88092572002-12-19 07:08:55 +0000223 {
Igor Sysoev3a17f242002-12-24 17:30:59 +0000224#if (NGX_DEBUG_EVENT)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000225 ngx_connection_t *c = (ngx_connection_t *) ev->data;
Igor Sysoeva9830112003-05-19 16:39:14 +0000226 ngx_log_debug(ev->log, "kqueue event deleted: %d: ft:%d" _
227 c->fd _ event);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000228#endif
Igor Sysoevdc479b42003-03-20 16:09:44 +0000229
230 /* if the event is still not passed to a kernel we will not pass it */
231
Igor Sysoev42feecb2002-12-15 06:25:09 +0000232 if (ev->index < --nchanges) {
233 e = (ngx_event_t *) change_list[nchanges].udata;
234 change_list[ev->index] = change_list[nchanges];
235 e->index = ev->index;
236 }
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000237
238 return NGX_OK;
239 }
240
Igor Sysoev6b863e32003-05-12 15:52:24 +0000241 /* when the file descriptor is closed a kqueue automatically deletes
242 its filters so we do not need to delete explicity the event
243 before the closing the file descriptor */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000244
Igor Sysoev3a17f242002-12-24 17:30:59 +0000245 if (flags & NGX_CLOSE_EVENT) {
Igor Sysoev42feecb2002-12-15 06:25:09 +0000246 return NGX_OK;
Igor Sysoev3a17f242002-12-24 17:30:59 +0000247 }
Igor Sysoev42feecb2002-12-15 06:25:09 +0000248
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000249 return ngx_kqueue_set_event(ev, event, EV_DELETE);
250}
251
Igor Sysoev42feecb2002-12-15 06:25:09 +0000252
Igor Sysoeva9830112003-05-19 16:39:14 +0000253static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000254{
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000255 struct timespec ts;
256 ngx_connection_t *c;
Igor Sysoev88092572002-12-19 07:08:55 +0000257
Igor Sysoeva9830112003-05-19 16:39:14 +0000258 c = ev->data;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000259
Igor Sysoev3a17f242002-12-24 17:30:59 +0000260#if (NGX_DEBUG_EVENT)
Igor Sysoeve4a25262003-06-06 14:59:20 +0000261 ngx_log_debug(ev->log, "kqueue set event: %d: ft:%d fl:%08x" _
Igor Sysoeva6717c42002-12-23 06:29:22 +0000262 c->fd _ filter _ flags);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000263#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000264
Igor Sysoeva9830112003-05-19 16:39:14 +0000265 if (nchanges >= max_changes) {
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000266 ngx_log_error(NGX_LOG_WARN, ev->log, 0,
Igor Sysoev31f88182002-09-27 15:05:29 +0000267 "kqueue change list is filled up");
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000268
Igor Sysoev88092572002-12-19 07:08:55 +0000269 ts.tv_sec = 0;
270 ts.tv_nsec = 0;
271
Igor Sysoeva9830112003-05-19 16:39:14 +0000272 if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) {
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000273 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed");
Igor Sysoev1af7c822002-09-13 14:47:42 +0000274 return NGX_ERROR;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000275 }
Igor Sysoev3a17f242002-12-24 17:30:59 +0000276
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000277 nchanges = 0;
278 }
279
Igor Sysoeva6717c42002-12-23 06:29:22 +0000280 change_list[nchanges].ident = c->fd;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000281 change_list[nchanges].filter = filter;
282 change_list[nchanges].flags = flags;
Igor Sysoev6b863e32003-05-12 15:52:24 +0000283 change_list[nchanges].udata = (void *) ((uintptr_t) ev | ev->instance);
Igor Sysoev6a644c62003-03-04 06:33:48 +0000284
285#if (HAVE_LOWAT_EVENT)
286
287 if ((flags & EV_ADD) && ev->lowat > 0) {
288 change_list[nchanges].fflags = NOTE_LOWAT;
289 change_list[nchanges].data = ev->lowat;
290
291 } else {
292 change_list[nchanges].fflags = 0;
293 change_list[nchanges].data = 0;
294 }
295
296#else
297
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000298 change_list[nchanges].fflags = 0;
299 change_list[nchanges].data = 0;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000300
301#endif
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000302
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000303 ev->index = nchanges;
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000304
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000305 nchanges++;
306
Igor Sysoev1af7c822002-09-13 14:47:42 +0000307 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000308}
309
Igor Sysoev42feecb2002-12-15 06:25:09 +0000310
Igor Sysoeva9830112003-05-19 16:39:14 +0000311static int ngx_kqueue_process_events(ngx_log_t *log)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000312{
Igor Sysoev6b863e32003-05-12 15:52:24 +0000313 int events, instance, i;
Igor Sysoev9b25d692003-01-26 21:08:14 +0000314 ngx_msec_t timer, delta;
Igor Sysoevd4324e62002-09-17 17:49:32 +0000315 ngx_event_t *ev;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000316 struct timeval tv;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000317 struct timespec ts, *tp;
318
Igor Sysoev404326f2003-01-24 06:20:47 +0000319 timer = ngx_event_find_timer();
320
321 if (timer) {
322 ts.tv_sec = timer / 1000;
323 ts.tv_nsec = (timer % 1000) * 1000000;
324 tp = &ts;
325 gettimeofday(&tv, NULL);
326 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000;
327
328 } else {
329 timer = 0;
330 delta = 0;
331 tp = NULL;
332 }
333
Igor Sysoev3a17f242002-12-24 17:30:59 +0000334#if (NGX_DEBUG_EVENT)
Igor Sysoev1af7c822002-09-13 14:47:42 +0000335 ngx_log_debug(log, "kevent timer: %d" _ timer);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000336#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000337
Igor Sysoeva9830112003-05-19 16:39:14 +0000338 events = kevent(ngx_kqueue, change_list, nchanges, event_list, nevents, tp);
Igor Sysoev88092572002-12-19 07:08:55 +0000339
Igor Sysoev1af7c822002-09-13 14:47:42 +0000340 if (events == -1) {
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000341 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "kevent() failed");
Igor Sysoev1af7c822002-09-13 14:47:42 +0000342 return NGX_ERROR;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000343 }
344
345 nchanges = 0;
346
347 if (timer) {
348 gettimeofday(&tv, NULL);
349 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
350
Igor Sysoeva9830112003-05-19 16:39:14 +0000351 /* The expired timers must be handled before a processing of the events
352 because the new timers can be added during a processing */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000353
354 ngx_event_expire_timers(delta);
355
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000356 } else {
Igor Sysoev3a17f242002-12-24 17:30:59 +0000357 if (events == 0) {
358 ngx_log_error(NGX_LOG_ALERT, log, 0,
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000359 "kevent() returned no events without timeout");
Igor Sysoev3a17f242002-12-24 17:30:59 +0000360 return NGX_ERROR;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000361 }
362 }
363
Igor Sysoev3a17f242002-12-24 17:30:59 +0000364#if (NGX_DEBUG_EVENT)
365 ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta);
366#endif
367
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000368 for (i = 0; i < events; i++) {
369
Igor Sysoev3a17f242002-12-24 17:30:59 +0000370#if (NGX_DEBUG_EVENT)
Igor Sysoev73009772003-02-06 17:21:13 +0000371 if (event_list[i].ident > 0x8000000) {
372 ngx_log_debug(log,
Igor Sysoeve4a25262003-06-06 14:59:20 +0000373 "kevent: %08x: ft:%d fl:%08x ff:%08x d:%d ud:%08x" _
Igor Sysoev73009772003-02-06 17:21:13 +0000374 event_list[i].ident _ event_list[i].filter _
375 event_list[i].flags _ event_list[i].fflags _
376 event_list[i].data _ event_list[i].udata);
377 } else {
378 ngx_log_debug(log,
Igor Sysoeve4a25262003-06-06 14:59:20 +0000379 "kevent: %d: ft:%d fl:%08x ff:%08x d:%d ud:%08x" _
Igor Sysoev73009772003-02-06 17:21:13 +0000380 event_list[i].ident _ event_list[i].filter _
381 event_list[i].flags _ event_list[i].fflags _
382 event_list[i].data _ event_list[i].udata);
383 }
Igor Sysoev3a17f242002-12-24 17:30:59 +0000384#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000385
386 if (event_list[i].flags & EV_ERROR) {
387 ngx_log_error(NGX_LOG_ALERT, log, event_list[i].data,
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000388 "kevent() error on %d", event_list[i].ident);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000389 continue;
390 }
391
392 ev = (ngx_event_t *) event_list[i].udata;
Igor Sysoev3a17f242002-12-24 17:30:59 +0000393
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000394 switch (event_list[i].filter) {
395
396 case EVFILT_READ:
397 case EVFILT_WRITE:
Igor Sysoevdc479b42003-03-20 16:09:44 +0000398
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000399 instance = (uintptr_t) ev & 1;
400 ev = (void *) ((uintptr_t) ev & ~1);
401
402 /* It's a stale event from a file descriptor
403 that was just closed in this iteration */
404
405 if (ev->active == 0 || ev->instance != instance) {
406 ngx_log_debug(log, "stale kevent");
407 continue;
408 }
409
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000410 ev->available = event_list[i].data;
411
412 if (event_list[i].flags & EV_EOF) {
413 ev->eof = 1;
414 ev->error = event_list[i].fflags;
415 }
416
Igor Sysoeva9830112003-05-19 16:39:14 +0000417 if (ev->oneshot && ev->timer_set) {
Igor Sysoev3a40d482002-09-12 14:42:29 +0000418 ngx_del_timer(ev);
Igor Sysoeva9830112003-05-19 16:39:14 +0000419 ev->timer_set = 0;
Igor Sysoev3a17f242002-12-24 17:30:59 +0000420 }
Igor Sysoev3a40d482002-09-12 14:42:29 +0000421
Igor Sysoev73009772003-02-06 17:21:13 +0000422 /* fall through */
423
424 case EVFILT_AIO:
425 ev->ready = 1;
426
Igor Sysoevd581fd52003-05-13 16:02:32 +0000427 ev->event_handler(ev);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000428
429 break;
430
Igor Sysoev73009772003-02-06 17:21:13 +0000431
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000432 default:
Igor Sysoev3a17f242002-12-24 17:30:59 +0000433 ngx_log_error(NGX_LOG_ALERT, log, 0,
434 "unknown kevent filter %d" _ event_list[i].filter);
435 }
436 }
437
Igor Sysoev1af7c822002-09-13 14:47:42 +0000438 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000439}
Igor Sysoeva9830112003-05-19 16:39:14 +0000440
441
442static void *ngx_kqueue_create_conf(ngx_pool_t *pool)
443{
444 ngx_kqueue_conf_t *kcf;
445
446 ngx_test_null(kcf, ngx_palloc(pool, sizeof(ngx_kqueue_conf_t)),
447 NGX_CONF_ERROR);
448
449 kcf->changes = NGX_CONF_UNSET;
450 kcf->events = NGX_CONF_UNSET;
451
452 return kcf;
453}
454
455
456static char *ngx_kqueue_init_conf(ngx_pool_t *pool, void *conf)
457{
458 ngx_kqueue_conf_t *kcf = conf;
459
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000460 ngx_conf_init_unsigned_value(kcf->changes, 512);
461 ngx_conf_init_unsigned_value(kcf->events, 512);
Igor Sysoeva9830112003-05-19 16:39:14 +0000462
463 return NGX_CONF_OK;
464}