On Sat, Dec 12, 2020 at 11:29:02AM +0000, Visa Hankala wrote:
> On Fri, Dec 11, 2020 at 09:35:59AM -0300, Martin Pieuchot wrote:
> > +/*
> > + * Convert given kqueue event into corresponding select(2) bit.
> > + */
> > +int
> > +pselcollect(struct proc *p, struct kevent *kevp, fd_set *pobits[3])
> > +{
> > +#ifdef DIAGNOSTIC
> > +   /* Filter out and lazily delete spurious events */
> > +   if ((unsigned long)kevp->udata != p->p_kq_serial) {
> > +           DPRINTFN(0, "select fd %u mismatched serial %lu\n",
> > +               (int)kevp->ident, p->p_kq_serial);
> > +           kevp->flags = EV_DISABLE|EV_DELETE;
> > +           kqueue_register(p->p_kq, kevp, p);
> > +           return (0);
> > +   }
> > +#endif
> 
> Shouldn't skipping of spurious events be taken into account in the
> main scan loop? Otherwise they may cause artifacts, such as premature
> timeout expiry when a wakeup is caused solely by a spurious event, or
> return of an incomplete result when spurious events eat capacity from
> nevents.

I think the filtering should be done already in kqueue_scan(). If the same
logic applies to poll(2), putting the filter under condition "kq == p->p_kq"
should be good enough, no need to be more general than that.

Filtering in kqueue_scan() would also allow efficient removal of the event
registrations because the knotes are readily at hand.

Reply via email to