1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* $OpenBSD: kqueue.c,v 1.5 2002/07/10 14:41:31 art Exp $ */ 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu> 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * All rights reserved. 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Redistribution and use in source and binary forms, with or without 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * modification, are permitted provided that the following conditions 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * are met: 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 1. Redistributions of source code must retain the above copyright 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * notice, this list of conditions and the following disclaimer. 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 2. Redistributions in binary form must reproduce the above copyright 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * notice, this list of conditions and the following disclaimer in the 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * documentation and/or other materials provided with the distribution. 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 3. The name of the author may not be used to endorse or promote products 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * derived from this software without specific prior written permission. 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_CONFIG_H 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "config.h" 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define _GNU_SOURCE 1 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/types.h> 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_SYS_TIME_H 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/time.h> 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/_libevent_time.h> 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/queue.h> 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/event.h> 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <signal.h> 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h> 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h> 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string.h> 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <unistd.h> 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <errno.h> 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <assert.h> 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_INTTYPES_H 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <inttypes.h> 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Some platforms apparently define the udata field of struct kevent as 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * intptr_t, whereas others define it as void*. There doesn't seem to be an 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * easy way to tell them apart via autoconf, so we need to use OS macros. */ 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__) 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define PTR_TO_UDATA(x) ((intptr_t)(x)) 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define PTR_TO_UDATA(x) (x) 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "event.h" 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "event-internal.h" 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "log.h" 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define EVLIST_X_KQINKERNEL 0x1000 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NEVENT 64 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct kqop { 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kevent *changes; 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int nchanges; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kevent *events; 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct event_list evsigevents[NSIG]; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int nevents; 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int kq; 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pid_t pid; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void *kq_init (struct event_base *); 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int kq_add (void *, struct event *); 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int kq_del (void *, struct event *); 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int kq_dispatch (struct event_base *, void *, struct timeval *); 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int kq_insert (struct kqop *, struct kevent *); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void kq_dealloc (struct event_base *, void *); 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst struct eventop kqops = { 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "kqueue", 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kq_init, 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kq_add, 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kq_del, 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kq_dispatch, 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kq_dealloc, 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1 /* need reinit */ 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void * 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottkq_init(struct event_base *base) 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i, kq; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kqop *kqueueop; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Disable kqueue when this environment variable is set */ 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evutil_getenv("EVENT_NOKQUEUE")) 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (NULL); 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(kqueueop = calloc(1, sizeof(struct kqop)))) 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (NULL); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Initalize the kernel queue */ 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ((kq = kqueue()) == -1) { 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_warn("kqueue"); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free (kqueueop); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (NULL); 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->kq = kq; 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->pid = getpid(); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Initalize fields */ 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->changes = malloc(NEVENT * sizeof(struct kevent)); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kqueueop->changes == NULL) { 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free (kqueueop); 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (NULL); 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->events = malloc(NEVENT * sizeof(struct kevent)); 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kqueueop->events == NULL) { 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free (kqueueop->changes); 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free (kqueueop); 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (NULL); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->nevents = NEVENT; 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* we need to keep track of multiple events per signal */ 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = 0; i < NSIG; ++i) { 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TAILQ_INIT(&kqueueop->evsigevents[i]); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Check for Mac OS X kqueue bug. */ 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->changes[0].ident = -1; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->changes[0].filter = EVFILT_READ; 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->changes[0].flags = EV_ADD; 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * If kqueue works, then kevent will succeed, and it will 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * stick an error in events[0]. If kqueue is broken, then 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * kevent will fail. 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kevent(kq, 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 || 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->events[0].ident != -1 || 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqueueop->events[0].flags != EV_ERROR) { 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_warn("%s: detected broken kqueue; not using.", __func__); 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(kqueueop->changes); 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(kqueueop->events); 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(kqueueop); 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott close(kq); 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (NULL); 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (kqueueop); 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottkq_insert(struct kqop *kqop, struct kevent *kev) 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int nevents = kqop->nevents; 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kqop->nchanges == nevents) { 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kevent *newchange; 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kevent *newresult; 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott nevents *= 2; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott newchange = realloc(kqop->changes, 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott nevents * sizeof(struct kevent)); 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (newchange == NULL) { 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_warn("%s: malloc", __func__); 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqop->changes = newchange; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott newresult = realloc(kqop->events, 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott nevents * sizeof(struct kevent)); 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * If we fail, we don't have to worry about freeing, 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the next realloc will pick it up. 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (newresult == NULL) { 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_warn("%s: malloc", __func__); 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqop->events = newresult; 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqop->nevents = nevents; 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(&kqop->changes[kqop->nchanges++], kev, sizeof(struct kevent)); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_debug(("%s: fd %d %s%s", 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott __func__, (int)kev->ident, 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev->filter == EVFILT_READ ? "EVFILT_READ" : "EVFILT_WRITE", 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev->flags == EV_DELETE ? " (del)" : "")); 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottkq_sighandler(int sig) 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Do nothing here */ 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottkq_dispatch(struct event_base *base, void *arg, struct timeval *tv) 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kqop *kqop = arg; 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kevent *changes = kqop->changes; 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kevent *events = kqop->events; 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct event *ev; 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timespec ts, *ts_p = NULL; 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i, res; 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (tv != NULL) { 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TIMEVAL_TO_TIMESPEC(tv, &ts); 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ts_p = &ts; 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott res = kevent(kqop->kq, changes, kqop->nchanges, 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott events, kqop->nevents, ts_p); 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kqop->nchanges = 0; 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (res == -1) { 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (errno != EINTR) { 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_warn("kevent"); 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_debug(("%s: kevent reports %d", __func__, res)); 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = 0; i < res; i++) { 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int which = 0; 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (events[i].flags & EV_ERROR) { 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Error messages that can happen, when a delete fails. 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * EBADF happens when the file discriptor has been 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * closed, 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * ENOENT when the file discriptor was closed and 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * then reopened. 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * EINVAL for some reasons not understood; EINVAL 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * should not be returned ever; but FreeBSD does :-\ 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * An error is also indicated when a callback deletes 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * an event we are still processing. In that case 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the data field is set to ENOENT. 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (events[i].data == EBADF || 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott events[i].data == EINVAL || 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott events[i].data == ENOENT) 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott errno = events[i].data; 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (events[i].filter == EVFILT_READ) { 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott which |= EV_READ; 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (events[i].filter == EVFILT_WRITE) { 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott which |= EV_WRITE; 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (events[i].filter == EVFILT_SIGNAL) { 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott which |= EV_SIGNAL; 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!which) 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (events[i].filter == EVFILT_SIGNAL) { 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct event_list *head = 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (struct event_list *)events[i].udata; 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TAILQ_FOREACH(ev, head, ev_signal_next) { 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_active(ev, which, events[i].data); 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev = (struct event *)events[i].udata; 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(ev->ev_events & EV_PERSIST)) 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev->ev_flags &= ~EVLIST_X_KQINKERNEL; 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_active(ev, which, 1); 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottkq_add(void *arg, struct event *ev) 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kqop *kqop = arg; 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kevent kev; 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev->ev_events & EV_SIGNAL) { 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int nsignal = EVENT_SIGNAL(ev); 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(nsignal >= 0 && nsignal < NSIG); 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (TAILQ_EMPTY(&kqop->evsigevents[nsignal])) { 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timespec timeout = { 0, 0 }; 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&kev, 0, sizeof(kev)); 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.ident = nsignal; 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.filter = EVFILT_SIGNAL; 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.flags = EV_ADD; 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.udata = PTR_TO_UDATA(&kqop->evsigevents[nsignal]); 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Be ready for the signal if it is sent any 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * time between now and the next call to 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * kq_dispatch. */ 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1) 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (_evsignal_set_handler(ev->ev_base, nsignal, 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kq_sighandler) == -1) 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TAILQ_INSERT_TAIL(&kqop->evsigevents[nsignal], ev, 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev_signal_next); 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev->ev_flags |= EVLIST_X_KQINKERNEL; 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev->ev_events & EV_READ) { 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&kev, 0, sizeof(kev)); 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.ident = ev->ev_fd; 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.filter = EVFILT_READ; 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef NOTE_EOF 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Make it behave like select() and poll() */ 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.fflags = NOTE_EOF; 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.flags = EV_ADD; 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(ev->ev_events & EV_PERSIST)) 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.flags |= EV_ONESHOT; 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.udata = PTR_TO_UDATA(ev); 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kq_insert(kqop, &kev) == -1) 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev->ev_flags |= EVLIST_X_KQINKERNEL; 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev->ev_events & EV_WRITE) { 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&kev, 0, sizeof(kev)); 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.ident = ev->ev_fd; 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.filter = EVFILT_WRITE; 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.flags = EV_ADD; 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(ev->ev_events & EV_PERSIST)) 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.flags |= EV_ONESHOT; 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.udata = PTR_TO_UDATA(ev); 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kq_insert(kqop, &kev) == -1) 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev->ev_flags |= EVLIST_X_KQINKERNEL; 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottkq_del(void *arg, struct event *ev) 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kqop *kqop = arg; 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kevent kev; 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(ev->ev_flags & EVLIST_X_KQINKERNEL)) 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev->ev_events & EV_SIGNAL) { 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int nsignal = EVENT_SIGNAL(ev); 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timespec timeout = { 0, 0 }; 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(nsignal >= 0 && nsignal < NSIG); 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TAILQ_REMOVE(&kqop->evsigevents[nsignal], ev, ev_signal_next); 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (TAILQ_EMPTY(&kqop->evsigevents[nsignal])) { 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&kev, 0, sizeof(kev)); 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.ident = nsignal; 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.filter = EVFILT_SIGNAL; 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.flags = EV_DELETE; 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Because we insert signal events 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * immediately, we need to delete them 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * immediately, too */ 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1) 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (_evsignal_restore_handler(ev->ev_base, 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott nsignal) == -1) 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev->ev_flags &= ~EVLIST_X_KQINKERNEL; 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev->ev_events & EV_READ) { 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&kev, 0, sizeof(kev)); 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.ident = ev->ev_fd; 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.filter = EVFILT_READ; 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.flags = EV_DELETE; 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kq_insert(kqop, &kev) == -1) 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev->ev_flags &= ~EVLIST_X_KQINKERNEL; 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev->ev_events & EV_WRITE) { 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&kev, 0, sizeof(kev)); 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.ident = ev->ev_fd; 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.filter = EVFILT_WRITE; 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kev.flags = EV_DELETE; 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kq_insert(kqop, &kev) == -1) 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ev->ev_flags &= ~EVLIST_X_KQINKERNEL; 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottkq_dealloc(struct event_base *base, void *arg) 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct kqop *kqop = arg; 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kqop->changes) 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(kqop->changes); 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kqop->events) 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(kqop->events); 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kqop->kq >= 0 && kqop->pid == getpid()) 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott close(kqop->kq); 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(kqop, 0, sizeof(struct kqop)); 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(kqop); 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 451