15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* $OpenBSD: kqueue.c,v 1.5 2002/07/10 14:41:31 art Exp $ */ 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu> 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that the following conditions 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are met: 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3. The name of the author may not be used to endorse or promote products 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * derived from this software without specific prior written permission. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CONFIG_H 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _GNU_SOURCE 1 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TIME_H 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/_libevent_time.h> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/queue.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/event.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_INTTYPES_H 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <inttypes.h> 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Some platforms apparently define the udata field of struct kevent as 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * intptr_t, whereas others define it as void*. There doesn't seem to be an 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * easy way to tell them apart via autoconf, so we need to use OS macros. */ 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTR_TO_UDATA(x) ((intptr_t)(x)) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PTR_TO_UDATA(x) (x) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "event.h" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "event-internal.h" 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "log.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EVLIST_X_KQINKERNEL 0x1000 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEVENT 64 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kqop { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kevent *changes; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nchanges; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kevent *events; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_list evsigevents[NSIG]; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nevents; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int kq; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pid_t pid; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *kq_init (struct event_base *); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int kq_add (void *, struct event *); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int kq_del (void *, struct event *); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int kq_dispatch (struct event_base *, void *, struct timeval *); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int kq_insert (struct kqop *, struct kevent *); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void kq_dealloc (struct event_base *, void *); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const struct eventop kqops = { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "kqueue", 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kq_init, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kq_add, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kq_del, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kq_dispatch, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kq_dealloc, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1 /* need reinit */ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void * 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)kq_init(struct event_base *base) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, kq; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kqop *kqueueop; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Disable kqueue when this environment variable is set */ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (evutil_getenv("EVENT_NOKQUEUE")) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(kqueueop = calloc(1, sizeof(struct kqop)))) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initalize the kernel queue */ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((kq = kqueue()) == -1) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_warn("kqueue"); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free (kqueueop); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->kq = kq; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->pid = getpid(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initalize fields */ 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->changes = malloc(NEVENT * sizeof(struct kevent)); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kqueueop->changes == NULL) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free (kqueueop); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->events = malloc(NEVENT * sizeof(struct kevent)); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kqueueop->events == NULL) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free (kqueueop->changes); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free (kqueueop); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->nevents = NEVENT; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we need to keep track of multiple events per signal */ 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < NSIG; ++i) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_INIT(&kqueueop->evsigevents[i]); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check for Mac OS X kqueue bug. */ 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->changes[0].ident = -1; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->changes[0].filter = EVFILT_READ; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->changes[0].flags = EV_ADD; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If kqueue works, then kevent will succeed, and it will 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * stick an error in events[0]. If kqueue is broken, then 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * kevent will fail. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kevent(kq, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 || 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->events[0].ident != -1 || 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqueueop->events[0].flags != EV_ERROR) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_warn("%s: detected broken kqueue; not using.", __func__); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(kqueueop->changes); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(kqueueop->events); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(kqueueop); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(kq); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (kqueueop); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)kq_insert(struct kqop *kqop, struct kevent *kev) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nevents = kqop->nevents; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kqop->nchanges == nevents) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kevent *newchange; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kevent *newresult; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nevents *= 2; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newchange = realloc(kqop->changes, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nevents * sizeof(struct kevent)); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newchange == NULL) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_warn("%s: malloc", __func__); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqop->changes = newchange; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newresult = realloc(kqop->events, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nevents * sizeof(struct kevent)); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If we fail, we don't have to worry about freeing, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the next realloc will pick it up. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newresult == NULL) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_warn("%s: malloc", __func__); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqop->events = newresult; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqop->nevents = nevents; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&kqop->changes[kqop->nchanges++], kev, sizeof(struct kevent)); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("%s: fd %d %s%s", 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __func__, (int)kev->ident, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev->filter == EVFILT_READ ? "EVFILT_READ" : "EVFILT_WRITE", 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev->flags == EV_DELETE ? " (del)" : "")); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)kq_sighandler(int sig) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Do nothing here */ 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)kq_dispatch(struct event_base *base, void *arg, struct timeval *tv) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kqop *kqop = arg; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kevent *changes = kqop->changes; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kevent *events = kqop->events; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event *ev; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timespec ts, *ts_p = NULL; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, res; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tv != NULL) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TIMEVAL_TO_TIMESPEC(tv, &ts); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ts_p = &ts; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = kevent(kqop->kq, changes, kqop->nchanges, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events, kqop->nevents, ts_p); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kqop->nchanges = 0; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res == -1) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (errno != EINTR) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_warn("kevent"); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("%s: kevent reports %d", __func__, res)); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < res; i++) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int which = 0; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events[i].flags & EV_ERROR) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Error messages that can happen, when a delete fails. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * EBADF happens when the file discriptor has been 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * closed, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ENOENT when the file discriptor was closed and 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then reopened. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * EINVAL for some reasons not understood; EINVAL 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should not be returned ever; but FreeBSD does :-\ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * An error is also indicated when a callback deletes 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an event we are still processing. In that case 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the data field is set to ENOENT. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events[i].data == EBADF || 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events[i].data == EINVAL || 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events[i].data == ENOENT) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errno = events[i].data; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events[i].filter == EVFILT_READ) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) which |= EV_READ; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (events[i].filter == EVFILT_WRITE) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) which |= EV_WRITE; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (events[i].filter == EVFILT_SIGNAL) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) which |= EV_SIGNAL; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!which) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events[i].filter == EVFILT_SIGNAL) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_list *head = 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (struct event_list *)events[i].udata; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_FOREACH(ev, head, ev_signal_next) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_active(ev, which, events[i].data); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev = (struct event *)events[i].udata; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(ev->ev_events & EV_PERSIST)) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags &= ~EVLIST_X_KQINKERNEL; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_active(ev, which, 1); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)kq_add(void *arg, struct event *ev) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kqop *kqop = arg; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kevent kev; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_events & EV_SIGNAL) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nsignal = EVENT_SIGNAL(ev); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(nsignal >= 0 && nsignal < NSIG); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TAILQ_EMPTY(&kqop->evsigevents[nsignal])) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timespec timeout = { 0, 0 }; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&kev, 0, sizeof(kev)); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.ident = nsignal; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.filter = EVFILT_SIGNAL; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.flags = EV_ADD; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.udata = PTR_TO_UDATA(&kqop->evsigevents[nsignal]); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Be ready for the signal if it is sent any 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * time between now and the next call to 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * kq_dispatch. */ 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (_evsignal_set_handler(ev->ev_base, nsignal, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kq_sighandler) == -1) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_INSERT_TAIL(&kqop->evsigevents[nsignal], ev, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev_signal_next); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags |= EVLIST_X_KQINKERNEL; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_events & EV_READ) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&kev, 0, sizeof(kev)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.ident = ev->ev_fd; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.filter = EVFILT_READ; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NOTE_EOF 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Make it behave like select() and poll() */ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.fflags = NOTE_EOF; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.flags = EV_ADD; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(ev->ev_events & EV_PERSIST)) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.flags |= EV_ONESHOT; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.udata = PTR_TO_UDATA(ev); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kq_insert(kqop, &kev) == -1) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags |= EVLIST_X_KQINKERNEL; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_events & EV_WRITE) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&kev, 0, sizeof(kev)); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.ident = ev->ev_fd; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.filter = EVFILT_WRITE; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.flags = EV_ADD; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(ev->ev_events & EV_PERSIST)) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.flags |= EV_ONESHOT; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.udata = PTR_TO_UDATA(ev); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kq_insert(kqop, &kev) == -1) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags |= EVLIST_X_KQINKERNEL; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)kq_del(void *arg, struct event *ev) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kqop *kqop = arg; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kevent kev; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(ev->ev_flags & EVLIST_X_KQINKERNEL)) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_events & EV_SIGNAL) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nsignal = EVENT_SIGNAL(ev); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timespec timeout = { 0, 0 }; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(nsignal >= 0 && nsignal < NSIG); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_REMOVE(&kqop->evsigevents[nsignal], ev, ev_signal_next); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TAILQ_EMPTY(&kqop->evsigevents[nsignal])) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&kev, 0, sizeof(kev)); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.ident = nsignal; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.filter = EVFILT_SIGNAL; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.flags = EV_DELETE; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Because we insert signal events 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * immediately, we need to delete them 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * immediately, too */ 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (_evsignal_restore_handler(ev->ev_base, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nsignal) == -1) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags &= ~EVLIST_X_KQINKERNEL; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_events & EV_READ) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&kev, 0, sizeof(kev)); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.ident = ev->ev_fd; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.filter = EVFILT_READ; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.flags = EV_DELETE; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kq_insert(kqop, &kev) == -1) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags &= ~EVLIST_X_KQINKERNEL; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_events & EV_WRITE) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&kev, 0, sizeof(kev)); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.ident = ev->ev_fd; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.filter = EVFILT_WRITE; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kev.flags = EV_DELETE; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kq_insert(kqop, &kev) == -1) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags &= ~EVLIST_X_KQINKERNEL; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)kq_dealloc(struct event_base *base, void *arg) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kqop *kqop = arg; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kqop->changes) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(kqop->changes); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kqop->events) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(kqop->events); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kqop->kq >= 0 && kqop->pid == getpid()) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(kqop->kq); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(kqop, 0, sizeof(struct kqop)); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(kqop); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 451