From: Tanaka Akira Date: 2004-02-29T04:25:21+09:00 Subject: Re: ruby-dev summary 22877-23014 In article <20040227152954.GS379@atdesk.com>, Paul Brannan writes: > What about non-blocking writes? non-blocking writes needs O_NONBLOCK. But it is difficult issue. > (I rarely put an fd in non-blocking mode to read, because I can easily > enough keep my app from blocking on a read by simply not reading when > there isn't data to read; if I put an fd in non-blocking mode, it is > almost always for writing). I imagine you want to avoid a situation like following. % ruby -e 'Thread.new { loop { STDERR.puts "e"; sleep 1 } } print "x" * 8192 sleep 10'|sleep 10 e -e:2:in `write': Broken pipe (Errno::EPIPE) from -e:2:in `print' from -e:2 Since Ruby doesn't use non-blocking writes on write operation, whole process blocks. Unfortunately Ruby doesn't handle non-blocking writes well. Ruby may lose some data on non-blocking writes. % ruby -rfcntl -e ' STDOUT.sync = true STDOUT.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) STDOUT.write "x" * 4097 STDOUT.write "y"'|(sleep 1; cat )|od -c 0000000 x x x x x x x x x x x x x x x x * 0010000 y 0010001 This is because stdio's fflush lose data on EAGAIN. stdio is not nonblocking friendly. So, for fixing non-blocking writes problem, Ruby should 1. abandon stdio and 2. set O_NONBLOCK on write(2) temporally or use timer like DJB. http://cr.yp.to/unix/nonblock.html I don't known when Ruby abandon stdio. Sigh. > I have code that expects that the non-blocking flag is not clear. The > rule should be to not mix non-blocking fds with code that expects a > blocking fd and vice versa. Yes. However it is difficult to know a fd is not used as blocking fd. stdio is used widely. Sometimes Ruby itself assumes fd blocking: [ruby-talk:66196], [ruby-talk:93726]. -- Tanaka Akira