kern/45291: kevent(2) ignores timeout if nevents == 0

John-Mark Gurney gurney_j at
Thu Oct 16 10:10:11 PDT 2003

Boris Nikolaus wrote this message on Thu, Oct 16, 2003 at 11:39 +0200:
> On Mon, Oct 13, 2003 at 12:47:16PM -0700, John-Mark Gurney wrote:
> > John Polstra wrote this message on Mon, Oct 13, 2003 at 09:37 -0700:
> > > On 13-Oct-2003 John-Mark Gurney wrote:
> > > > Synopsis: kevent(2) ignores timeout if nevents == 0
> > > > 
> > > > State-Changed-From-To: open->feedback
> > > > State-Changed-By: jmg
> > > > State-Changed-When: Mon Oct 13 00:46:53 PDT 2003
> > > > State-Changed-Why: 
> > > > to quote the man page: If timeout is a non-NULL pointer, it specifies 
> > > > a maximum interval to wait for an event,
> > > > 
> > > > The behavior is correct since you wanted to wait for 0 events, and since 
> > > > it has delivered all the events it can (none), it returns.  Unless provide 
> > > > with good reason (or maybe a patch to the manpage to document this feature?) 
> > > > I will close the PR in 5 days.
> I still disagree:
> To quote the poll and select man pages:
> poll:   If timeout is neither zero nor INFTIM (-1), it specifies a maximum
>         interval to wait for any file descriptor to become ready, in
>         milliseconds.
> select: If timeout is a non-nil pointer, it specifies the maximum interval to
>         wait for the selection to complete.
> In both cases, it is a very similar text to the kevent man page, but for
> poll and select, the behaviour is to wait if nfds = 0 (and so no event
> can be returned).

but the thing is that nfds is different for select than for kqueue.
nfds specifies the maxium file descriptors to check, not number of
events to wait for.  In fact, after reading select's manpage, this
misfeature isn't documented, and select really should return EINVAL
if nfds is 0, and -1 is an invalid fd (which is the last fd that
select is suppose to check)..

> > Simple fix, you wait for a single event, adding a struct kevent such as:
> > 	struct kevent ke;
> >     ret = kevent(qfd, NULL, 0, &ke, 1, &ts);
> > 
> > makes it wait the full 10 seconds.  so, are you suggesting that we change
> > the behavior to wait for the timeout to expire before we return ANY
> > events? (because that is what your suggesting).  Special caseing when
> > someone passes in 0 is not good IMO... it will probably brake lots of
> > code that may in advertantly set as ts, but expect immediate return
> > because of not specifing any return events.
> I think, you misunderstood me: I do not want kevent to wait for the timeout
> to expire before returning ANY events, I want kevent to wait for the timeout
> when NO event has signalled! This is not a special case, I think the current
> implementation handles nevent = 0 as special case, as it returns before the
> timeout has expired although no event has been signalled.

no, I understood you perfectly fine, but I'm saying that special casing
this is BAD, and that if we didn't make it a special case, then we would
have a problem of always waiting.

> Your fix to call kevent with nevents = 1 will remove an event from the event
> queue. This may be a solution for the trivial example program of the PR
> (as there are no events registered for the queue) but not the expected
> behaviour in a real main loop.

Considering that you should be using nanosleep instead of abusing yet
another system call, you get what you pain for..

> To summarize, I think kevent should not return until
> - it has found any signalled events, or
> - the timeout expires, or
> - a (non-ignored) signal arrives
> as this is the behaviour of poll() and select() and IMHO the intuitive
> behaviour.

Unless you come up with a patch in the next few days, I will close this.
patches speak louder than words. and make sure you update the manpage
to expliciately state this, patches w/o manpage updates aren't acceptable.

  John-Mark Gurney				Voice: +1 415 225 5579

     "All that I will do, has been done, All that I have, has not."

More information about the freebsd-bugs mailing list