In article <000001c4134c$0cbe5920$0300a8c0@boulba>,
  "yannick" <yannick / dazzlebox.com> writes:

> You are right, after further tests; it looks like a thread scheduling
> problem, it could perhaps be solved by making the thread critical, but
> then it only return the EAGAIN error. Well, it seems I'm stock here,
> better find another way around :-)

I recommend sysread instead of IO#read with nonblocking mode.

However, your first script is interesting because it transit
multithread to singlethread after sock.read(100) is started.

When there are two or more threads, Ruby calls select(2) before each
IO operation for thread scheduling.  But Ruby doesn't call select(2)
when there is only one thread.

Your first script invokes following system calls.

% strace -e read,write,select ruby tst1
...
select(0, [], [], [], {0, 0})           = 0 (Timeout)
select(6, [5], [], [], {1, 999368})     = 0 (Timeout)
select(6, [5], [], [], {0, 3115})       = 0 (Timeout)
select(6, [5], [], [], {0, 0})          = 0 (Timeout)
select(9, [5], [7], [], NULL)           = 2 (in [5], out [7])
write(1, "try to read it...\n", 18)     = 18
(*1) select(9, [8], [], [], {0, 0})          = 0 (Timeout)
write(1, "send a message\n", 15)        = 15
select(9, [8], [7], [], NULL)           = 1 (out [7])
write(7, "message", 7)                  = 7
select(9, [8], [7], [], NULL)           = 2 (in [8], out [7])
select(9, [8], [], [], {0, 0})          = 1 (in [8], left {0, 0})
write(7, "\n", 1)                       = 1
(*2) read(8, "message\n", 1024)              = 8
(*3) read(8, 0x4001a000, 1024)               = -1 EAGAIN (Resource temporarily unavailable)
write(1, "done !\n", 7)                 = 7

System calls corresponding to sock.read(100) is (*1), (*2) and (*3)

(*1) Check sock is readable or not.  Since it is not readable yet,
     it blocks and switch to other thread.
(*2) Read 8bytes from sock: "message\n".
(*3) Occur EAGAIN.  It terminates sock.read(100).

What interesting is that select is not called before (*3).
If select is called at (*3), it blocks forever.
This means that there are no thread other than the main thread.
Actually the client thread is finished before (*2).

So sock.read(100) blocks at first(*1) by select because multithread.
But it doesn't block at last(*3) because singlethread.

I think this behavior is very confusing.
-- 
Tanaka Akira