Add support for EV_RECEIPT and EV_DISPATCH flags
authormikeb <mikeb@openbsd.org>
Wed, 31 May 2017 14:52:05 +0000 (14:52 +0000)
committermikeb <mikeb@openbsd.org>
Wed, 31 May 2017 14:52:05 +0000 (14:52 +0000)
From FreeBSD via Jan Schreiber <jes at posteo ! de>, thanks!
OK tedu, bluhm

lib/libc/sys/kqueue.2
sys/kern/kern_event.c
sys/sys/event.h

index 35ca23d..613a8f8 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: kqueue.2,v 1.33 2016/08/13 17:05:02 tedu Exp $
+.\"    $OpenBSD: kqueue.2,v 1.34 2017/05/31 14:52:05 mikeb Exp $
 .\"
 .\" Copyright (c) 2000 Jonathan Lemon
 .\" All rights reserved.
@@ -26,7 +26,7 @@
 .\"
 .\" $FreeBSD: src/lib/libc/sys/kqueue.2,v 1.18 2001/02/14 08:48:35 guido Exp $
 .\"
-.Dd $Mdocdate: August 13 2016 $
+.Dd $Mdocdate: May 31 2017 $
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -184,10 +184,25 @@ Disable the event so
 .Fn kevent
 will not return it.
 The filter itself is not disabled.
+.It Dv EV_DISPATCH
+Disable the event source immediately after delivery of an event.
+See
+.Dv EV_DISABLE
+above.
 .It Dv 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 Dv EV_RECEIPT
+Causes
+.Fn kevent
+to return with
+.Dv EV_ERROR
+set without draining any pending events after updating events in the kqueue.
+When a filter is successfully added the
+.Va data
+field will be zero.
+This flag is useful for making bulk changes to a kqueue.
 .It Dv EV_ONESHOT
 Causes the event to return only the first occurrence of the filter
 being triggered.
index 561b9b2..e9a66f6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_event.c,v 1.78 2017/02/11 19:51:06 guenther Exp $        */
+/*     $OpenBSD: kern_event.c,v 1.79 2017/05/31 14:52:05 mikeb Exp $   */
 
 /*-
  * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -512,7 +512,7 @@ sys_kevent(struct proc *p, void *v, register_t *retval)
                        kevp = &kq->kq_kev[i];
                        kevp->flags &= ~EV_SYSFLAGS;
                        error = kqueue_register(kq, kevp, p);
-                       if (error) {
+                       if (error || (kevp->flags & EV_RECEIPT)) {
                                if (SCARG(uap, nevents) != 0) {
                                        kevp->flags = EV_ERROR;
                                        kevp->data = error;
@@ -788,9 +788,13 @@ start:
                        kn->kn_fop->f_detach(kn);
                        knote_drop(kn, p, p->p_fd);
                        s = splhigh();
-               } else if (kn->kn_flags & EV_CLEAR) {
-                       kn->kn_data = 0;
-                       kn->kn_fflags = 0;
+               } else if (kn->kn_flags & (EV_CLEAR | EV_DISPATCH)) {
+                       if (kn->kn_flags & EV_CLEAR) {
+                               kn->kn_data = 0;
+                               kn->kn_fflags = 0;
+                       }
+                       if (kn->kn_flags & EV_DISPATCH)
+                               kn->kn_status |= KN_DISABLED;
                        kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
                        kq->kq_count--;
                } else {
index 13b370b..c359092 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: event.h,v 1.24 2017/05/31 07:12:28 tedu Exp $ */
+/*     $OpenBSD: event.h,v 1.25 2017/05/31 14:52:05 mikeb Exp $        */
 
 /*-
  * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -69,6 +69,8 @@ struct kevent {
 /* flags */
 #define EV_ONESHOT     0x0010          /* only report one occurrence */
 #define EV_CLEAR       0x0020          /* clear event state after reporting */
+#define EV_RECEIPT     0x0040          /* force EV_ERROR on success, data=0 */
+#define EV_DISPATCH    0x0080          /* disable event after reporting */
 
 #define EV_SYSFLAGS    0xF000          /* reserved by system */
 #define EV_FLAG1       0x2000          /* filter-specific flag */