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 */