blob: 26e109b1a72c2d2e70d8b24b90eef576bf01629c [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
Igor Sysoev9d639522003-07-07 06:11:50 +000026static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle);
27static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, 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 Sysoev0a280a32003-10-12 16:49:16 +0000154 ngx_event_flags = NGX_USE_ONESHOT_EVENT
Igor Sysoev1e7ec9d2003-02-11 07:14:40 +0000155#if (HAVE_CLEAR_EVENT)
Igor Sysoev0a280a32003-10-12 16:49:16 +0000156 |NGX_USE_CLEAR_EVENT
Igor Sysoevb7387572003-03-11 20:38:13 +0000157#else
158 |NGX_USE_LEVEL_EVENT
Igor Sysoev73009772003-02-06 17:21:13 +0000159#endif
Igor Sysoev6a644c62003-03-04 06:33:48 +0000160#if (HAVE_LOWAT_EVENT)
161 |NGX_HAVE_LOWAT_EVENT
162#endif
Igor Sysoev1e7ec9d2003-02-11 07:14:40 +0000163 |NGX_HAVE_KQUEUE_EVENT;
164
Igor Sysoev31f88182002-09-27 15:05:29 +0000165 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000166}
167
Igor Sysoev42feecb2002-12-15 06:25:09 +0000168
Igor Sysoev340b03b2003-07-04 15:10:33 +0000169static void ngx_kqueue_done(ngx_cycle_t *cycle)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000170{
Igor Sysoeva9830112003-05-19 16:39:14 +0000171 if (close(ngx_kqueue) == -1) {
Igor Sysoev340b03b2003-07-04 15:10:33 +0000172 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
173 "kqueue close() failed");
Igor Sysoev6a644c62003-03-04 06:33:48 +0000174 }
Igor Sysoeva9830112003-05-19 16:39:14 +0000175
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000176 ngx_kqueue = -1;
177
Igor Sysoev340b03b2003-07-04 15:10:33 +0000178 ngx_event_timer_done(cycle);
Igor Sysoeva9830112003-05-19 16:39:14 +0000179
180 ngx_free(change_list);
181 ngx_free(event_list);
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000182
183 change_list = NULL;
184 event_list = NULL;
185 max_changes = 0;
186 nchanges = 0;
187 nevents = 0;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000188}
189
190
Igor Sysoeva9830112003-05-19 16:39:14 +0000191static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000192{
Igor Sysoeva9830112003-05-19 16:39:14 +0000193 ngx_connection_t *c;
194
Igor Sysoev3a17f242002-12-24 17:30:59 +0000195 ev->active = 1;
Igor Sysoev1c13c662003-05-20 15:37:55 +0000196 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0;
Igor Sysoev3a40d482002-09-12 14:42:29 +0000197
Igor Sysoeva6717c42002-12-23 06:29:22 +0000198 if (nchanges > 0
199 && ev->index < nchanges
Igor Sysoeva9830112003-05-19 16:39:14 +0000200 && (void *) ((uintptr_t) change_list[ev->index].udata & ~1) == ev)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000201 {
Igor Sysoeva9830112003-05-19 16:39:14 +0000202 c = ev->data;
203 ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
Igor Sysoev425a42c2003-10-27 16:16:17 +0000204 "previous event on #%d were not passed in kernel", c->fd);
Igor Sysoevdc479b42003-03-20 16:09:44 +0000205
Igor Sysoeva9830112003-05-19 16:39:14 +0000206 return NGX_ERROR;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000207 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000208
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000209 return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
210}
211
Igor Sysoev42feecb2002-12-15 06:25:09 +0000212
Igor Sysoeva9830112003-05-19 16:39:14 +0000213static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000214{
Igor Sysoev3a17f242002-12-24 17:30:59 +0000215 ngx_event_t *e;
216
217 ev->active = 0;
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000218
Igor Sysoeva6717c42002-12-23 06:29:22 +0000219 if (nchanges > 0
220 && ev->index < nchanges
Igor Sysoev6b863e32003-05-12 15:52:24 +0000221 && (void *) ((uintptr_t) change_list[ev->index].udata & ~1) == ev)
Igor Sysoev88092572002-12-19 07:08:55 +0000222 {
Igor Sysoev3a17f242002-12-24 17:30:59 +0000223#if (NGX_DEBUG_EVENT)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000224 ngx_connection_t *c = (ngx_connection_t *) ev->data;
Igor Sysoeva9830112003-05-19 16:39:14 +0000225 ngx_log_debug(ev->log, "kqueue event deleted: %d: ft:%d" _
226 c->fd _ event);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000227#endif
Igor Sysoevdc479b42003-03-20 16:09:44 +0000228
229 /* if the event is still not passed to a kernel we will not pass it */
230
Igor Sysoev42feecb2002-12-15 06:25:09 +0000231 if (ev->index < --nchanges) {
232 e = (ngx_event_t *) change_list[nchanges].udata;
233 change_list[ev->index] = change_list[nchanges];
234 e->index = ev->index;
235 }
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000236
237 return NGX_OK;
238 }
239
Igor Sysoev0a280a32003-10-12 16:49:16 +0000240 /*
241 * 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.
244 */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000245
Igor Sysoev3a17f242002-12-24 17:30:59 +0000246 if (flags & NGX_CLOSE_EVENT) {
Igor Sysoev42feecb2002-12-15 06:25:09 +0000247 return NGX_OK;
Igor Sysoev3a17f242002-12-24 17:30:59 +0000248 }
Igor Sysoev42feecb2002-12-15 06:25:09 +0000249
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000250 return ngx_kqueue_set_event(ev, event, EV_DELETE);
251}
252
Igor Sysoev42feecb2002-12-15 06:25:09 +0000253
Igor Sysoeva9830112003-05-19 16:39:14 +0000254static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000255{
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000256 struct timespec ts;
257 ngx_connection_t *c;
Igor Sysoev88092572002-12-19 07:08:55 +0000258
Igor Sysoeva9830112003-05-19 16:39:14 +0000259 c = ev->data;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000260
Igor Sysoev3a17f242002-12-24 17:30:59 +0000261#if (NGX_DEBUG_EVENT)
Igor Sysoeve4a25262003-06-06 14:59:20 +0000262 ngx_log_debug(ev->log, "kqueue set event: %d: ft:%d fl:%08x" _
Igor Sysoeva6717c42002-12-23 06:29:22 +0000263 c->fd _ filter _ flags);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000264#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000265
Igor Sysoeva9830112003-05-19 16:39:14 +0000266 if (nchanges >= max_changes) {
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000267 ngx_log_error(NGX_LOG_WARN, ev->log, 0,
Igor Sysoev31f88182002-09-27 15:05:29 +0000268 "kqueue change list is filled up");
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000269
Igor Sysoev88092572002-12-19 07:08:55 +0000270 ts.tv_sec = 0;
271 ts.tv_nsec = 0;
272
Igor Sysoeva9830112003-05-19 16:39:14 +0000273 if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) {
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000274 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed");
Igor Sysoev1af7c822002-09-13 14:47:42 +0000275 return NGX_ERROR;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000276 }
Igor Sysoev3a17f242002-12-24 17:30:59 +0000277
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000278 nchanges = 0;
279 }
280
Igor Sysoeva6717c42002-12-23 06:29:22 +0000281 change_list[nchanges].ident = c->fd;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000282 change_list[nchanges].filter = filter;
283 change_list[nchanges].flags = flags;
Igor Sysoev6b863e32003-05-12 15:52:24 +0000284 change_list[nchanges].udata = (void *) ((uintptr_t) ev | ev->instance);
Igor Sysoev6a644c62003-03-04 06:33:48 +0000285
286#if (HAVE_LOWAT_EVENT)
287
288 if ((flags & EV_ADD) && ev->lowat > 0) {
289 change_list[nchanges].fflags = NOTE_LOWAT;
290 change_list[nchanges].data = ev->lowat;
291
292 } else {
293 change_list[nchanges].fflags = 0;
294 change_list[nchanges].data = 0;
295 }
296
297#else
298
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000299 change_list[nchanges].fflags = 0;
300 change_list[nchanges].data = 0;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000301
302#endif
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000303
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000304 ev->index = nchanges;
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000305
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000306 nchanges++;
307
Igor Sysoev1af7c822002-09-13 14:47:42 +0000308 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000309}
310
Igor Sysoev42feecb2002-12-15 06:25:09 +0000311
Igor Sysoeva9830112003-05-19 16:39:14 +0000312static int ngx_kqueue_process_events(ngx_log_t *log)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000313{
Igor Sysoev6b863e32003-05-12 15:52:24 +0000314 int events, instance, i;
Igor Sysoev9d639522003-07-07 06:11:50 +0000315 ngx_err_t err;
Igor Sysoev9b25d692003-01-26 21:08:14 +0000316 ngx_msec_t timer, delta;
Igor Sysoevd4324e62002-09-17 17:49:32 +0000317 ngx_event_t *ev;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000318 struct timeval tv;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000319 struct timespec ts, *tp;
320
Igor Sysoev404326f2003-01-24 06:20:47 +0000321 timer = ngx_event_find_timer();
322
323 if (timer) {
324 ts.tv_sec = timer / 1000;
325 ts.tv_nsec = (timer % 1000) * 1000000;
326 tp = &ts;
327 gettimeofday(&tv, NULL);
328 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000;
329
330 } else {
331 timer = 0;
332 delta = 0;
333 tp = NULL;
334 }
335
Igor Sysoev3a17f242002-12-24 17:30:59 +0000336#if (NGX_DEBUG_EVENT)
Igor Sysoev1af7c822002-09-13 14:47:42 +0000337 ngx_log_debug(log, "kevent timer: %d" _ timer);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000338#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000339
Igor Sysoeva9830112003-05-19 16:39:14 +0000340 events = kevent(ngx_kqueue, change_list, nchanges, event_list, nevents, tp);
Igor Sysoev88092572002-12-19 07:08:55 +0000341
Igor Sysoev1af7c822002-09-13 14:47:42 +0000342 if (events == -1) {
Igor Sysoev9d639522003-07-07 06:11:50 +0000343 err = ngx_errno;
344 } else {
345 err = 0;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000346 }
347
348 nchanges = 0;
349
350 if (timer) {
351 gettimeofday(&tv, NULL);
352 delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
353
Igor Sysoev9d639522003-07-07 06:11:50 +0000354#if (NGX_DEBUG_EVENT)
355 ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta);
356#endif
357
Igor Sysoeva9830112003-05-19 16:39:14 +0000358 /* The expired timers must be handled before a processing of the events
359 because the new timers can be added during a processing */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000360
361 ngx_event_expire_timers(delta);
362
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000363 } else {
Igor Sysoev3a17f242002-12-24 17:30:59 +0000364 if (events == 0) {
365 ngx_log_error(NGX_LOG_ALERT, log, 0,
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000366 "kevent() returned no events without timeout");
Igor Sysoev3a17f242002-12-24 17:30:59 +0000367 return NGX_ERROR;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000368 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000369
Igor Sysoev3a17f242002-12-24 17:30:59 +0000370#if (NGX_DEBUG_EVENT)
Igor Sysoev9d639522003-07-07 06:11:50 +0000371 ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000372#endif
Igor Sysoev9d639522003-07-07 06:11:50 +0000373 }
374
375 if (err) {
376 ngx_log_error(NGX_LOG_ALERT, log, err, "kevent() failed");
377 return NGX_ERROR;
378 }
Igor Sysoev3a17f242002-12-24 17:30:59 +0000379
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000380 for (i = 0; i < events; i++) {
381
Igor Sysoev3a17f242002-12-24 17:30:59 +0000382#if (NGX_DEBUG_EVENT)
Igor Sysoev73009772003-02-06 17:21:13 +0000383 if (event_list[i].ident > 0x8000000) {
384 ngx_log_debug(log,
Igor Sysoeve4a25262003-06-06 14:59:20 +0000385 "kevent: %08x: ft:%d fl:%08x ff:%08x d:%d ud:%08x" _
Igor Sysoev73009772003-02-06 17:21:13 +0000386 event_list[i].ident _ event_list[i].filter _
387 event_list[i].flags _ event_list[i].fflags _
388 event_list[i].data _ event_list[i].udata);
389 } else {
390 ngx_log_debug(log,
Igor Sysoeve4a25262003-06-06 14:59:20 +0000391 "kevent: %d: ft:%d fl:%08x ff:%08x d:%d ud:%08x" _
Igor Sysoev73009772003-02-06 17:21:13 +0000392 event_list[i].ident _ event_list[i].filter _
393 event_list[i].flags _ event_list[i].fflags _
394 event_list[i].data _ event_list[i].udata);
395 }
Igor Sysoev3a17f242002-12-24 17:30:59 +0000396#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000397
398 if (event_list[i].flags & EV_ERROR) {
399 ngx_log_error(NGX_LOG_ALERT, log, event_list[i].data,
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000400 "kevent() error on %d", event_list[i].ident);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000401 continue;
402 }
403
404 ev = (ngx_event_t *) event_list[i].udata;
Igor Sysoev3a17f242002-12-24 17:30:59 +0000405
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000406 switch (event_list[i].filter) {
407
408 case EVFILT_READ:
409 case EVFILT_WRITE:
Igor Sysoevdc479b42003-03-20 16:09:44 +0000410
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000411 instance = (uintptr_t) ev & 1;
412 ev = (void *) ((uintptr_t) ev & ~1);
413
414 /* It's a stale event from a file descriptor
415 that was just closed in this iteration */
416
417 if (ev->active == 0 || ev->instance != instance) {
418 ngx_log_debug(log, "stale kevent");
419 continue;
420 }
421
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000422 ev->available = event_list[i].data;
423
424 if (event_list[i].flags & EV_EOF) {
Igor Sysoevab0c4f52003-10-28 15:45:41 +0000425 ev->kq_eof = 1;
426 ev->kq_errno = event_list[i].fflags;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000427 }
428
Igor Sysoeva9830112003-05-19 16:39:14 +0000429 if (ev->oneshot && ev->timer_set) {
Igor Sysoev3a40d482002-09-12 14:42:29 +0000430 ngx_del_timer(ev);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000431 }
Igor Sysoev3a40d482002-09-12 14:42:29 +0000432
Igor Sysoev0a280a32003-10-12 16:49:16 +0000433 ev->ready = 1;
434
435 ev->event_handler(ev);
436
437 break;
Igor Sysoev73009772003-02-06 17:21:13 +0000438
439 case EVFILT_AIO:
Igor Sysoev68ee8f12003-10-30 08:51:06 +0000440 ev->complete = 1;
441 ev->ready = 1;
Igor Sysoev73009772003-02-06 17:21:13 +0000442
Igor Sysoevd581fd52003-05-13 16:02:32 +0000443 ev->event_handler(ev);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000444
445 break;
446
Igor Sysoev73009772003-02-06 17:21:13 +0000447
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000448 default:
Igor Sysoev3a17f242002-12-24 17:30:59 +0000449 ngx_log_error(NGX_LOG_ALERT, log, 0,
450 "unknown kevent filter %d" _ event_list[i].filter);
451 }
452 }
453
Igor Sysoev1af7c822002-09-13 14:47:42 +0000454 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000455}
Igor Sysoeva9830112003-05-19 16:39:14 +0000456
457
Igor Sysoev9d639522003-07-07 06:11:50 +0000458static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle)
Igor Sysoeva9830112003-05-19 16:39:14 +0000459{
460 ngx_kqueue_conf_t *kcf;
461
Igor Sysoev9d639522003-07-07 06:11:50 +0000462 ngx_test_null(kcf, ngx_palloc(cycle->pool, sizeof(ngx_kqueue_conf_t)),
Igor Sysoeva9830112003-05-19 16:39:14 +0000463 NGX_CONF_ERROR);
464
465 kcf->changes = NGX_CONF_UNSET;
466 kcf->events = NGX_CONF_UNSET;
467
468 return kcf;
469}
470
471
Igor Sysoev9d639522003-07-07 06:11:50 +0000472static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf)
Igor Sysoeva9830112003-05-19 16:39:14 +0000473{
474 ngx_kqueue_conf_t *kcf = conf;
475
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000476 ngx_conf_init_unsigned_value(kcf->changes, 512);
477 ngx_conf_init_unsigned_value(kcf->events, 512);
Igor Sysoeva9830112003-05-19 16:39:14 +0000478
479 return NGX_CONF_OK;
480}