summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/kqueue.25
-rw-r--r--sys/kern/kern_event.c6
-rw-r--r--sys/sys/event.h2
3 files changed, 11 insertions, 2 deletions
diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2
index 1e5e2b5..63f5a4d 100644
--- a/lib/libc/sys/kqueue.2
+++ b/lib/libc/sys/kqueue.2
@@ -201,6 +201,11 @@ 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
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 92afec2..2630894 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1445,15 +1445,17 @@ start:
*kevp = kn->kn_kevent;
KQ_LOCK(kq);
KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal);
- if (kn->kn_flags & EV_CLEAR) {
+ if (kn->kn_flags & (EV_CLEAR | EV_DISPATCH)) {
/*
* Manually clear knotes who weren't
* 'touch'ed.
*/
- if (touch == 0) {
+ if (touch == 0 && 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
diff --git a/sys/sys/event.h b/sys/sys/event.h
index eb0fefd..2934b7b 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -72,6 +72,8 @@ struct kevent {
/* flags */
#define EV_ONESHOT 0x0010 /* only report one occurrence */
#define EV_CLEAR 0x0020 /* clear event state after reporting */
+ /* 0x0040 reserved for EV_RECEIPT */
+#define EV_DISPATCH 0x0080 /* disable event after reporting */
#define EV_SYSFLAGS 0xF000 /* reserved by system */
#define EV_FLAG1 0x2000 /* filter-specific flag */
OpenPOWER on IntegriCloud