Nonblocking I/O and POLL_BUG
Per Hedeland
per at erix.ericsson.se
Mon Oct 25 12:37:51 UTC 1999
Russ Allbery wrote:
>I'm working on redoing lib/nonblocking.c so that we can get rid of some
>more rat's mazes in configure.in, and in so doing I ran across the fact
>that we've been using O_NDELAY rather than O_NONBLOCK as the flag. From
>the comment in my new rework:
O_NONBLOCK is of course the way to go (where available) - however...
>** The semantics of O_NDELAY are that if the read
>** would block, it returns 0 instead.
The semantics of O_NDELAY on SysV-heritage systems, that is (broken as
usual:-).
>newsfeed:~/log> grep 'readclose' news.notice | wc -l
> 532
>
>because INN has been misinterpreting a blocked read as a remote close in
>some circumstances. While I was in this code, though, I also found I was
>getting a lot of "cant read: Resource temporarily unavailable" messages in
>my logs, which sounds like EAGAIN on read wasn't being handled correctly.
>When I went looking for that, I saw that what I'd consider to be correct
>handling of EAGAIN (pretend as if the connection had never selected true
>for reading and return to the select loop) was protected by #ifdef
>POLL_BUG.
I'm not quite sure I follow you here, but: If select() (or poll())
returns saying that a descriptor is ready for reading, and you get
EAGAIN when first trying to read it, that is most definitely a bug.
Likewise if that read returns 0 without a "real" EOF condition
existing. Plus of course per above one has to wonder why one on Solaris
would *ever* get EAGAIN on read() when using O_NDELAY to set
non-blocking mode...
>Checking my logs, I don't see nearly enough of those error messages to
>worry about INN spinning in a tight loop of EAGAINs, but that's just
>Solaris. Does anyone know if there are any problems with this on other
>platforms?
I think that if you don't get spurious EAGAINs on Solaris, you won't get
them anywhere:-) - it seems that OS may occasionally return it on just
about *any* system call, non-blocking mode or not. It has probably
improved in recent times though, the question is how much you need to
worry about the code being run on older versions.
Anyway, some (4-5) years ago I had reason to investigate how to get a
working non-blocking mode on various Unices and descriptor types,
resulting in the rather depressing summary enclosed below - a POSIX-
compliant O_NONBLOCK should hopefully be more commonly available these
days, but I haven't re-run the tests. I still have the program that did
them around in case anyone's interested in doing that, though.
--Per Hedeland
per at erix.ericsson.se
--------------------------
Explanations:
AG - returned -1, errno = EAGAIN
WB - returned -1, errno = EWOULDBLOCK
AG=WB - returned -1, errno = EAGAIN = EWOULDBLOCK
0 - returned 0 (ouch!:-)
n.a. - not available
fail - fcntl/ioctl returned -1
block - fcntl/ioctl returned 0 but didn't set non-blocking mode (ooouch!:-)
fcntl O_NONBLOCK fcntl O_NDELAY ioctl FIONBIO
pipe socket tty pipe socket tty pipe socket tty
SunOS 4.1.3
read AG AG AG WB WB WB WB WB WB
write AG AG AG WB WB WB WB WB WB
/usr/5bin/cc
read AG AG AG 0 0 0 WB WB WB
write AG AG AG 0 0 block WB WB WB
SunOS 5.2
read AG=WB AG=WB AG=WB 0 AG=WB 0 n.a. n.a. n.a.
write AG=WB AG=WB block 0 AG=WB block n.a. n.a. n.a.
-DBSD_COMP
read AG=WB AG=WB AG=WB 0 AG=WB 0 0 AG=WB 0
write AG=WB AG=WB block 0 AG=WB block 0 AG=WB block
AIX 3.2
read AG=WB block AG=WB 0 block 0 block AG=WB fail
write AG=WB block AG=WB 0 block 0 block AG=WB fail
-D_BSD
read AG=WB block AG=WB AG=WB block AG=WB block AG=WB fail
write AG=WB block AG=WB AG=WB block AG=WB block AG=WB fail
-lbsd
read AG=WB AG=WB AG=WB 0 block 0 AG=WB AG=WB AG=WB
write AG=WB AG=WB AG=WB 0 block 0 AG=WB AG=WB AG=WB
-D_BSD -lbsd
read AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB
write AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB
Ultrix 4.3
read AG block block AG WB WB AG WB WB
write WB block block WB WB block WB WB block
-YPOSIX
read AG block AG AG WB block AG WB block
write AG block block AG WB block AG WB block
-YSYSTEM_FIVE
read AG block block AG 0 0 AG 0 0
write 0 block block 0 0 block 0 0 block
OSF/1 1.3
read AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB
write AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB AG=WB
HP-UX 9.01
read AG AG AG 0 0 0 fail WB fail
write AG AG AG 0 0 block fail WB fail
Interactive 3.2
-Xp -D_POSIX_SOURCE
read AG AG AG n.a. n.a. n.a. n.a. n.a. n.a.
write AG AG block n.a. n.a. n.a. n.a. n.a. n.a.
-DNO_TERMIOS
read AG AG AG AG AG AG n.a. n.a. n.a.
write AG AG block AG AG block n.a. n.a. n.a.
More information about the inn-workers
mailing list