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.

Reply via email to