summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2020-12-16 15:06:12 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2020-12-16 15:06:12 +0000
commit6321ec393a4e42cc31e473d520d538d03a9cda66 (patch)
tree223f538cb7779323625007319129609e70ec8bb2
parent23767b889e46b9559214105cc580d77f39804328 (diff)
Link kqpoll instances to fd_kqlist.
This lets the system remove kqpoll-related event registrations when a file descriptor is closed. OK mpi@
-rw-r--r--sys/kern/kern_event.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 8a9cc2caf9d..2aaecbac1f6 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.148 2020/12/15 04:48:18 visa Exp $ */
+/* $OpenBSD: kern_event.c,v 1.149 2020/12/16 15:06:11 visa Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -168,12 +168,17 @@ KQREF(struct kqueue *kq)
void
KQRELE(struct kqueue *kq)
{
- struct filedesc *fdp;
-
if (atomic_dec_int_nv(&kq->kq_refs) > 0)
return;
- fdp = kq->kq_fdp;
+ kqueue_free(kq);
+}
+
+void
+kqueue_free(struct kqueue *kq)
+{
+ struct filedesc *fdp = kq->kq_fdp;
+
if (rw_status(&fdp->fd_lock) == RW_WRITE) {
LIST_REMOVE(kq, kq_next);
} else {
@@ -182,12 +187,6 @@ KQRELE(struct kqueue *kq)
fdpunlock(fdp);
}
- kqueue_free(kq);
-}
-
-void
-kqueue_free(struct kqueue *kq)
-{
free(kq->kq_knlist, M_KEVENT, kq->kq_knlistsize *
sizeof(struct knlist));
hashfree(kq->kq_knhash, KN_HASHSIZE, M_KEVENT);
@@ -509,12 +508,17 @@ void
kqpoll_init(void)
{
struct proc *p = curproc;
+ struct filedesc *fdp;
if (p->p_kq != NULL)
return;
p->p_kq = kqueue_alloc(p->p_fd);
p->p_kq_serial = arc4random();
+ fdp = p->p_fd;
+ fdplock(fdp);
+ LIST_INSERT_HEAD(&fdp->fd_kqlist, p->p_kq, kq_next);
+ fdpunlock(fdp);
}
void