Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src PR/50506: Tobias Nygren: kqueue(2) lacks EV_DISPATCH/EV_RECE...



details:   https://anonhg.NetBSD.org/src/rev/cab5bace3632
branches:  trunk
changeset: 342140:cab5bace3632
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Dec 08 14:52:06 2015 +0000

description:
PR/50506: Tobias Nygren: kqueue(2) lacks EV_DISPATCH/EV_RECEIPT support

diffstat:

 lib/libc/sys/kqueue.2 |  18 ++++++++++++++++--
 sys/kern/kern_event.c |  13 +++++++++----
 sys/sys/event.h       |   4 +++-
 3 files changed, 28 insertions(+), 7 deletions(-)

diffs (116 lines):

diff -r cfc408c5d4ba -r cab5bace3632 lib/libc/sys/kqueue.2
--- a/lib/libc/sys/kqueue.2     Tue Dec 08 14:42:24 2015 +0000
+++ b/lib/libc/sys/kqueue.2     Tue Dec 08 14:52:06 2015 +0000
@@ -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 @@
 .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.
diff -r cfc408c5d4ba -r cab5bace3632 sys/kern/kern_event.c
--- a/sys/kern/kern_event.c     Tue Dec 08 14:42:24 2015 +0000
+++ b/sys/kern/kern_event.c     Tue Dec 08 14:52:06 2015 +0000
@@ -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 @@
                        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 @@
                        }
                        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 @@
                                /* 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 @@
        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 -r cfc408c5d4ba -r cab5bace3632 sys/sys/event.h
--- a/sys/sys/event.h   Tue Dec 08 14:42:24 2015 +0000
+++ b/sys/sys/event.h   Tue Dec 08 14:52:06 2015 +0000
@@ -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@localhost>
@@ -74,6 +74,8 @@
 /* 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 */



Home | Main Index | Thread Index | Old Index