From: Tanaka Akira Date: 2005-07-18T03:28:43+09:00 Subject: Re: Nonblocking Sockets In article <022c01c58a8c$e2e462c0$6442a8c0@musicbox>, "Bill Kelly" writes: > Interesting, doesn't that imply IPSocket#recvfrom is > essentially broken for NONBLOCK semantics? What I mean > is, if the socket is in nonblocking mode, and recvfrom() > gets an EAGAIN, shouldn't it just return nil to the > caller? (Or whatever the TCP methods do in a NONBLOCK > situation?) Why should it ever "block" in a NONBLOCK > situation? Ruby's nonblocking behaviour is not well designed. So it should be redesigned anyway. However nonblocking I/O is used for several reasons. There is a case that it is fine that an I/O method hides nonblockingness. For example, nonblocking I/O which is used to avoid process blocking by write(2) is such case. Assume a threaded (non-forking) network server program which use IO#read to read a request and IO#write to write a response and it doesn't use nonblocking I/O until someone reports DoS problem because IO#write may block the server process instead of the thread which invokes IO#write. If some I/O methods behaves differently between blocking mode and nonblocking mode, it makes hard to fix the DoS problem: simply set an socket to nonblocking mode by fcntl may not work well because nonblocking method behavior may not appropriate for the server program. So all I/O invocation must be examined or nonblocking mode must be set only around IO#write method. Note that IO#read in Ruby 1.8 behaves differently between the modes. So I think it is reasonable that I/O methods hides nonblocking behavior: retrying when EAGAIN and partial result. Current Ruby doesn't do it well, though. I guess there is a case which needs nonblocking behaviour visible from script. I'm not sure good design to proviede nonblocking behaviour for such script, though. -- Tanaka Akira