kqueue EV_RECEIPT and EV_DISPATCH

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

kqueue EV_RECEIPT and EV_DISPATCH

jes@posteo.de
Hi,

I recently stumbled upon software that relies on EV_RECEIPT and
EV_DISPATCH to be available as flags. It also showed up as dependency
for a Rust crate.
FreeBSD has it since 8.1 and OSX since 10.5.
Patch is below.

mike@ looked throug, thanks a lot!

Jan

Index: sys/kern/kern_event.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.78
diff -u -p -u -r1.78 kern_event.c
--- sys/kern/kern_event.c 11 Feb 2017 19:51:06 -0000 1.78
+++ sys/kern/kern_event.c 30 May 2017 22:38:49 -0000
@@ -512,7 +512,7 @@ sys_kevent(struct proc *p, void *v, regi
  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: sys/sys/event.h
===================================================================
RCS file: /cvs/src/sys/sys/event.h,v
retrieving revision 1.23
diff -u -p -u -r1.23 event.h
--- sys/sys/event.h 24 Sep 2016 18:39:17 -0000 1.23
+++ sys/sys/event.h 30 May 2017 22:31:04 -0000
@@ -68,6 +68,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 */
Index: lib/libc/sys/kqueue.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/kqueue.2,v
retrieving revision 1.33
diff -u -p -u -r1.33 kqueue.2
--- lib/libc/sys/kqueue.2 13 Aug 2016 17:05:02 -0000 1.33
+++ lib/libc/sys/kqueue.2 30 May 2017 22:30:29 -0000
@@ -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.

Reply | Threaded
Open this post in threaded view
|

Re: kqueue EV_RECEIPT and EV_DISPATCH

Ted Unangst-6
Jan Schreiber wrote:
> Hi,
>
> I recently stumbled upon software that relies on EV_RECEIPT and
> EV_DISPATCH to be available as flags. It also showed up as dependency
> for a Rust crate.
> FreeBSD has it since 8.1 and OSX since 10.5.
> Patch is below.

not sure I see the point, but gotta keep up with the joneses.

patch does look simple. ok with me.

Reply | Threaded
Open this post in threaded view
|

Re: kqueue EV_RECEIPT and EV_DISPATCH

Mike Belopuhov-5
In reply to this post by jes@posteo.de
On Wed, May 31, 2017 at 08:37 +0200, Jan Schreiber wrote:

> Hi,
>
> I recently stumbled upon software that relies on EV_RECEIPT and
> EV_DISPATCH to be available as flags. It also showed up as dependency
> for a Rust crate.
> FreeBSD has it since 8.1 and OSX since 10.5.
> Patch is below.
>
> mike@ looked throug, thanks a lot!
>

That was me (mikeb@).

> Jan
>
> Index: sys/kern/kern_event.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_event.c,v
> retrieving revision 1.78
> diff -u -p -u -r1.78 kern_event.c
> --- sys/kern/kern_event.c 11 Feb 2017 19:51:06 -0000 1.78
> +++ sys/kern/kern_event.c 30 May 2017 22:38:49 -0000
> @@ -512,7 +512,7 @@ sys_kevent(struct proc *p, void *v, regi
>   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: sys/sys/event.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/event.h,v
> retrieving revision 1.23
> diff -u -p -u -r1.23 event.h
> --- sys/sys/event.h 24 Sep 2016 18:39:17 -0000 1.23
> +++ sys/sys/event.h 30 May 2017 22:31:04 -0000
> @@ -68,6 +68,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 */
> Index: lib/libc/sys/kqueue.2
> ===================================================================
> RCS file: /cvs/src/lib/libc/sys/kqueue.2,v
> retrieving revision 1.33
> diff -u -p -u -r1.33 kqueue.2
> --- lib/libc/sys/kqueue.2 13 Aug 2016 17:05:02 -0000 1.33
> +++ lib/libc/sys/kqueue.2 30 May 2017 22:30:29 -0000
> @@ -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.
>

We've tweaked the description for EV_RECEIPT a bit because FreeBSD
version didn't make a whole lot sense.

Reply | Threaded
Open this post in threaded view
|

Re: kqueue EV_RECEIPT and EV_DISPATCH

Alexander Bluhm
On Wed, May 31, 2017 at 02:07:19PM +0200, Mike Belopuhov wrote:

> On Wed, May 31, 2017 at 08:37 +0200, Jan Schreiber wrote:
> > Hi,
> >
> > I recently stumbled upon software that relies on EV_RECEIPT and
> > EV_DISPATCH to be available as flags. It also showed up as dependency
> > for a Rust crate.
> > FreeBSD has it since 8.1 and OSX since 10.5.
> > Patch is below.
> >
> > mike@ looked throug, thanks a lot!
> >
>
> That was me (mikeb@).

Then you should commit it.  OK bluhm@

>
> > Jan
> >
> > Index: sys/kern/kern_event.c
> > ===================================================================
> > RCS file: /cvs/src/sys/kern/kern_event.c,v
> > retrieving revision 1.78
> > diff -u -p -u -r1.78 kern_event.c
> > --- sys/kern/kern_event.c 11 Feb 2017 19:51:06 -0000 1.78
> > +++ sys/kern/kern_event.c 30 May 2017 22:38:49 -0000
> > @@ -512,7 +512,7 @@ sys_kevent(struct proc *p, void *v, regi
> >   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: sys/sys/event.h
> > ===================================================================
> > RCS file: /cvs/src/sys/sys/event.h,v
> > retrieving revision 1.23
> > diff -u -p -u -r1.23 event.h
> > --- sys/sys/event.h 24 Sep 2016 18:39:17 -0000 1.23
> > +++ sys/sys/event.h 30 May 2017 22:31:04 -0000
> > @@ -68,6 +68,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 */
> > Index: lib/libc/sys/kqueue.2
> > ===================================================================
> > RCS file: /cvs/src/lib/libc/sys/kqueue.2,v
> > retrieving revision 1.33
> > diff -u -p -u -r1.33 kqueue.2
> > --- lib/libc/sys/kqueue.2 13 Aug 2016 17:05:02 -0000 1.33
> > +++ lib/libc/sys/kqueue.2 30 May 2017 22:30:29 -0000
> > @@ -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.
> >
>
> We've tweaked the description for EV_RECEIPT a bit because FreeBSD
> version didn't make a whole lot sense.