diff options
| author | christos <christos@NetBSD.org> | 2015-12-08 14:52:06 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2015-12-08 14:52:06 +0000 |
| commit | 0babdab098f352ba9ffbe89fd69c937dddcd505e (patch) | |
| tree | 5eab054fe7645087af192e7e31370214ccbb632e /sys | |
| parent | 25acac336c2d5233c7a80b53db4bcf7b9723e3e8 (diff) | |
PR/50506: Tobias Nygren: kqueue(2) lacks EV_DISPATCH/EV_RECEIPT support
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/kern/kern_event.c | 13 | ||||
| -rw-r--r-- | sys/sys/event.h | 4 |
2 files changed, 12 insertions, 5 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 603fdfaf55e..c265f77d3f5 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_event.c,v 1.83 2015/03/02 19:24:53 christos Exp $ */ +/* $NetBSD: kern_event.c,v 1.84 2015/12/08 14:52:06 christos Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.83 2015/03/02 19:24:53 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.84 2015/12/08 14:52:06 christos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -867,7 +867,7 @@ kevent1(register_t *retval, int fd, kevp->flags &= ~EV_SYSFLAGS; /* register each knote */ error = kqueue_register(kq, kevp); - if (error) { + if (error || (kevp->flags & EV_RECEIPT)) { if (nevents != 0) { kevp->flags = EV_ERROR; kevp->data = error; @@ -1229,6 +1229,7 @@ kqueue_scan(file_t *fp, size_t maxevents, struct kevent *ulistp, } if ((kn->kn_flags & EV_ONESHOT) == 0) { mutex_spin_exit(&kq->kq_lock); + KASSERT(kn->kn_fop->f_event != NULL); KERNEL_LOCK(1, NULL); /* XXXSMP */ rv = (*kn->kn_fop->f_event)(kn, 0); KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */ @@ -1258,7 +1259,10 @@ kqueue_scan(file_t *fp, size_t maxevents, struct kevent *ulistp, /* clear state after retrieval */ kn->kn_data = 0; kn->kn_fflags = 0; - kn->kn_status &= ~KN_ACTIVE; + kn->kn_status &= ~(KN_QUEUED|KN_ACTIVE); + } else if (kn->kn_flags & EV_DISPATCH) { + kn->kn_status |= KN_DISABLED; + kn->kn_status &= ~(KN_QUEUED|KN_ACTIVE); } else { /* add event back on list */ kq_check(kq); @@ -1510,6 +1514,7 @@ knote(struct klist *list, long hint) struct knote *kn, *tmpkn; SLIST_FOREACH_SAFE(kn, list, kn_selnext, tmpkn) { + KASSERT(kn->kn_fop->f_event != NULL); if ((*kn->kn_fop->f_event)(kn, hint)) knote_activate(kn); } diff --git a/sys/sys/event.h b/sys/sys/event.h index b1040f81c15..0387ec5ae4b 100644 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -1,4 +1,4 @@ -/* $NetBSD: event.h,v 1.24 2015/01/14 22:21:00 christos Exp $ */ +/* $NetBSD: event.h,v 1.25 2015/12/08 14:52:06 christos Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org> @@ -74,6 +74,8 @@ struct kevent { /* flags */ #define EV_ONESHOT 0x0010U /* only report one occurrence */ #define EV_CLEAR 0x0020U /* clear event state after reporting */ +#define EV_RECEIPT 0x0040U /* force EV_ERROR on success, data=0 */ +#define EV_DISPATCH 0x0080U /* disable event after reporting */ #define EV_SYSFLAGS 0xF000U /* reserved by system */ #define EV_FLAG1 0x2000U /* filter-specific flag */ |
