From a96d88d343f8e72bf9b7b2edd2b6a13466e2edb6 Mon Sep 17 00:00:00 2001 From: yasuoka Date: Sat, 23 Mar 2024 22:51:49 +0000 Subject: [PATCH] In kq_del(), delete matching EV_ADD entries to prevent libevent from passing both EV_ADD and EV_DELETE for the same fd to kevent(). ok visa --- lib/libevent/kqueue.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/libevent/kqueue.c b/lib/libevent/kqueue.c index f61da384376..e076213a7b3 100644 --- a/lib/libevent/kqueue.c +++ b/lib/libevent/kqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kqueue.c,v 1.42 2022/12/27 23:05:55 jmc Exp $ */ +/* $OpenBSD: kqueue.c,v 1.43 2024/03/23 22:51:49 yasuoka Exp $ */ /* * Copyright 2000-2002 Niels Provos @@ -358,6 +358,7 @@ kq_add(void *arg, struct event *ev) static int kq_del(void *arg, struct event *ev) { + int i, j; struct kqop *kqop = arg; struct kevent kev; @@ -391,6 +392,21 @@ kq_del(void *arg, struct event *ev) return (0); } + for (i = j = 0; i < kqop->nchanges; i++) { + if (kqop->changes[i].udata == ev && + (kqop->changes[i].flags & EV_ADD) != 0) + continue; /* delete this */ + if (i != j) + memcpy(&kqop->changes[j], &kqop->changes[i], + sizeof(struct kevent)); + j++; + } + if (kqop->nchanges != j) { + kqop->nchanges = j; + ev->ev_flags &= ~EVLIST_X_KQINKERNEL; + return (0); + } + if (ev->ev_events & EV_READ) { memset(&kev, 0, sizeof(kev)); kev.ident = ev->ev_fd; -- 2.20.1