Module Name: src
Committed By: christos
Date: Tue Dec 8 14:52:06 UTC 2015
Modified Files:
src/lib/libc/sys: kqueue.2
src/sys/kern: kern_event.c
src/sys/sys: event.h
Log Message:
PR/50506: Tobias Nygren: kqueue(2) lacks EV_DISPATCH/EV_RECEIPT support
To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/lib/libc/sys/kqueue.2
cvs rdiff -u -r1.83 -r1.84 src/sys/kern/kern_event.c
cvs rdiff -u -r1.24 -r1.25 src/sys/sys/event.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/sys/kqueue.2
diff -u src/lib/libc/sys/kqueue.2:1.34 src/lib/libc/sys/kqueue.2:1.35
--- src/lib/libc/sys/kqueue.2:1.34 Mon Mar 2 14:24:19 2015
+++ src/lib/libc/sys/kqueue.2 Tue Dec 8 09:52:06 2015
@@ -1,4 +1,4 @@
-.\" $NetBSD: kqueue.2,v 1.34 2015/03/02 19:24:19 christos Exp $
+.\" $NetBSD: kqueue.2,v 1.35 2015/12/08 14:52:06 christos Exp $
.\"
.\" Copyright (c) 2000 Jonathan Lemon
.\" All rights reserved.
@@ -32,7 +32,7 @@
.\"
.\" $FreeBSD: src/lib/libc/sys/kqueue.2,v 1.22 2001/06/27 19:55:57 dd Exp $
.\"
-.Dd March 2, 2015
+.Dd December 8, 2015
.Dt KQUEUE 2
.Os
.Sh NAME
@@ -210,10 +210,24 @@ Disable the event so
.Fn kevent
will not return it.
The filter itself is not disabled.
+.It EV_DISPATCH
+Disable the event source immediately after delivery of an event.
+See
+.Dv EV_DISABLE
+above.
.It EV_DELETE
Removes the event from the kqueue.
Events which are attached to file descriptors are automatically deleted
on the last close of the descriptor.
+.It EV_RECEIPT
+This flag is useful for making bulk changes to a kqueue without draining
+any pending events.
+When passed as input, it forces
+.Dv EV_ERROR
+to always be returned.
+When a filter is successfully added the
+.Va data
+field will be zero.
.It EV_ONESHOT
Causes the event to return only the first occurrence of the filter
being triggered.
Index: src/sys/kern/kern_event.c
diff -u src/sys/kern/kern_event.c:1.83 src/sys/kern/kern_event.c:1.84
--- src/sys/kern/kern_event.c:1.83 Mon Mar 2 14:24:53 2015
+++ src/sys/kern/kern_event.c Tue Dec 8 09:52:06 2015
@@ -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
}
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
/* 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);
}
Index: src/sys/sys/event.h
diff -u src/sys/sys/event.h:1.24 src/sys/sys/event.h:1.25
--- src/sys/sys/event.h:1.24 Wed Jan 14 17:21:00 2015
+++ src/sys/sys/event.h Tue Dec 8 09:52:06 2015
@@ -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 <[email protected]>
@@ -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 */