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.