On Sat, 27 Mar 2004, Tanaka Akira wrote:

> 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.

can you please elaborate on this?  why exactly?


> 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.

if it is confusing to you, we are all doomed!  your explanations are really
insightful and i for one _really_ appreciate you taking to time to enlighten

maybe dave could have you write the new pickaxe thread section! ;-)

-a
-- 
===============================================================================
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL     :: http://www.ngdc.noaa.gov/stp/
| TRY     :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done 
===============================================================================