kern/45291: kevent(2) ignores timeout if nevents == 0
boris at cs.tu-berlin.de
Sun Oct 19 06:02:51 PDT 2003
On Thu, Oct 16, 2003 at 10:09:58AM -0700, John-Mark Gurney wrote:
> Boris Nikolaus wrote this message on Thu, Oct 16, 2003 at 11:39 +0200:
> > 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)..
Select's manpage says, it checks all file descriptors from 0 to
nfds - 1. The set of whole numbers which are >= 0 and <= -1 is empty,
so select has to check no descriptors and waits for the timeout. This
is exactly what select does, so this behaviour is implicitely
Changing select's behaviour as you suggest would break many software
as this behavious is often used, both in main loops (which have to
observe a set of file descriptors and timers and do not want to
handle the case "only timers left" in a special way) and explicitely
for sleeping (before microsleep/nanosleep have been invented, there
was no function for sleeping with resolution below seconds, so the
common way for sleeping in these cases was to call select with
nfds == 0).
> > > 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.
No, IMHO returning immediately if nevents == 0 is the special case, I just
want kevent to behave all times the same way, independent of nevents:
If nevents > 0, kevent waits for an event to occur, the timeout to expire
or an interruption by a signal. And so should kevent if nevent == 0:
Wait for an event to occur (even if it cannot show which event signalled),
the timeout to expire or a signal to arrive! Make as few special cases
> 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.
No problem, I attach patches for both FreeBSD 4.9RC and 5.1. Simply apply
the source patch to
and the man page patch to
The patches are very simple, but in case of questions do not hesitate to
More information about the freebsd-bugs