In article <20040227152954.GS379 / atdesk.com>,
  Paul Brannan <pbrannan / atdesk.com> 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