Allow select() calls on FDs that are already ready
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 1 Apr 2016 19:46:31 +0000 (15:46 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 5 Apr 2016 19:42:19 +0000 (15:42 -0400)
commit6cb2d8c1ce773f36d8729a5495bc641eb0fb4a61
tree1c412468a123d578dff956698f48cd23796ec708
parent59f4fdbc89c2018872d70c0e7336fafbf5eb69cf
Allow select() calls on FDs that are already ready

The super-spurious select() required programs to drain an FD completely
(i.e. read until you get an EAGAIN), though it is legal to just keep
asking.  Unfortunately, we have an app that does that (dropbear), so we
need to check if an FD is readable manually.

The bug was:

- packet arrives
- tap fires
- user wakes up
- user reads some of it, but not all of it
- user selects

Then we never way up, since a tap will not fire again.

If the user checks the FD (as we do here) and it has no data, then we can
sleep safely, knowing that an edge-triggered event will occur (since we
know the underlying queue was empty at some point).

Hopefully we don't need to do this for write().

Note that this doesn't work for "normal" disk files.  We don't have a way
to tell if a file is readable.  That's basically kernel support for select.

Also note that this 'fix' could mask errors related to changing the FD set
between successive calls to select().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
user/iplib/select.c