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