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 <jle...@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 */

Reply via email to