33 static void *ngx_kqueue_create_conf(
ngx_cycle_t *cycle);
34 static char *ngx_kqueue_init_conf(
ngx_cycle_t *cycle,
void *conf);
47 static struct kevent *change_list, *change_list0, *change_list1;
48 static struct kevent *event_list;
49 static ngx_uint_t max_changes, nchanges, nevents;
82 ngx_kqueue_create_conf,
92 ngx_kqueue_process_changes,
93 ngx_kqueue_process_events,
121 #if (NGX_HAVE_TIMER_EVENT)
139 if (list_mutex == NULL) {
144 if (kevent_mutex == NULL) {
151 if (max_changes < kcf->changes) {
156 if (kevent(
ngx_kqueue, change_list, (
int) nchanges, NULL, 0, &ts)
170 change_list0 =
ngx_alloc(kcf->changes *
sizeof(
struct kevent),
172 if (change_list0 == NULL) {
180 change_list1 =
ngx_alloc(kcf->changes *
sizeof(
struct kevent),
182 if (change_list1 == NULL) {
186 change_list = change_list0;
189 max_changes = kcf->changes;
191 if (nevents < kcf->events) {
196 event_list =
ngx_alloc(kcf->events *
sizeof(
struct kevent), cycle->
log);
197 if (event_list == NULL) {
206 #if (NGX_HAVE_TIMER_EVENT)
210 kev.filter = EVFILT_TIMER;
211 kev.flags = EV_ADD|EV_ENABLE;
219 if (kevent(
ngx_kqueue, &kev, 1, NULL, 0, &ts) == -1) {
221 "kevent(EVFILT_TIMER) failed");
230 #if (NGX_HAVE_CLEAR_EVENT)
236 #if (NGX_HAVE_LOWAT_EVENT)
240 nevents = kcf->events;
255 "kqueue close() failed");
296 if (ev->
index < nchanges
297 && ((uintptr_t) change_list[ev->
index].udata & (uintptr_t) ~1)
300 if (change_list[ev->index].flags == EV_DISABLE) {
308 "kevent activated: %d: ft:%i",
311 if (ev->index < --nchanges) {
313 ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
314 change_list[ev->index] = change_list[nchanges];
315 e->
index = ev->index;
326 "previous event on #%d were not passed in kernel", c->
fd);
335 rc = ngx_kqueue_set_event(ev, event, EV_ADD|EV_ENABLE|flags);
354 if (ev->
index < nchanges
355 && ((uintptr_t) change_list[ev->
index].udata & (uintptr_t) ~1)
359 "kevent deleted: %d: ft:%i",
366 if (ev->index < nchanges) {
368 ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
369 change_list[ev->index] = change_list[nchanges];
370 e->
index = ev->index;
396 rc = ngx_kqueue_set_event(ev, event, flags);
414 "kevent set event: %d: ft:%i fl:%04Xi",
415 c->fd, filter, flags);
417 if (nchanges >= max_changes) {
419 "kqueue change list is filled up");
424 if (kevent(
ngx_kqueue, change_list, (
int) nchanges, NULL, 0, &ts)
434 kev = &change_list[nchanges];
437 kev->filter = (short) filter;
438 kev->flags = (u_short) flags;
441 if (filter == EVFILT_VNODE) {
442 kev->fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND
443 |NOTE_ATTRIB|NOTE_RENAME
444 #if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
445 || __FreeBSD_version >= 500018
452 #if (NGX_HAVE_LOWAT_EVENT)
454 kev->fflags = NOTE_LOWAT;
467 ev->
index = nchanges;
476 if (kevent(
ngx_kqueue, change_list, (
int) nchanges, NULL, 0, &ts)
499 struct timespec ts, *tp;
502 if (ngx_kqueue_process_changes(cycle, 0) ==
NGX_ERROR) {
518 ts.tv_sec = timer / 1000;
519 ts.tv_nsec = (timer % 1000) * 1000000;
527 #if (NGX_DARWIN_KEVENT_BUG)
535 "kevent timer: %M, changes: %d", timer, n);
537 events = kevent(
ngx_kqueue, change_list, n, event_list, (
int) nevents, tp);
546 "kevent events: %d", events);
572 "kevent() returned no events without timeout");
578 for (i = 0; i < events; i++) {
580 ngx_kqueue_dump_event(cycle->
log, &event_list[i]);
582 if (event_list[i].flags & EV_ERROR) {
584 "kevent() error on %d filter:%d flags:%04Xd",
585 event_list[i].ident, event_list[i].filter,
586 event_list[i].flags);
590 #if (NGX_HAVE_TIMER_EVENT)
592 if (event_list[i].filter == EVFILT_TIMER) {
601 switch (event_list[i].filter) {
606 instance = (uintptr_t) ev & 1;
607 ev = (
ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
617 "kevent: stale event %p", ev);
622 ngx_kqueue_dump_event(ev->
log, &event_list[i]);
633 ev->posted_available = event_list[
i].data;
635 if (event_list[i].flags & EV_EOF) {
637 ev->posted_errno = event_list[
i].fflags;
649 if (event_list[i].flags & EV_EOF) {
651 ev->kq_errno = event_list[
i].fflags;
671 "unexpected kevent() filter %d",
672 event_list[i].filter);
700 struct kevent *changes;
712 changes = change_list;
713 if (change_list == change_list0) {
714 change_list = change_list1;
716 change_list = change_list0;
728 "kevent changes: %d", n);
730 if (kevent(
ngx_kqueue, changes, n, NULL, 0, &ts) == -1) {
733 cycle->
log, err,
"kevent() failed");
747 ngx_kqueue_dump_event(
ngx_log_t *log,
struct kevent *kev)
750 (kev->ident > 0x8000000 && kev->ident != (
unsigned) -1) ?
751 "kevent: %p: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p":
752 "kevent: %d: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p",
753 kev->ident, kev->filter,
754 kev->flags, kev->fflags,
755 kev->
data, kev->udata);
777 ngx_kqueue_init_conf(
ngx_cycle_t *cycle,
void *conf)