In article <1126966623.981939.26328.nullmailer / x31.priv.netlab.jp>,
  Yukihiro Matsumoto <matz / ruby-lang.org> writes:

> |2005-09-16 から NetBSD で test/socket/test_tcp.rb がブロックするようになっています。
> |http://www.rubyist.net/~akr/chkbuild/netbsd-2.0.1/ruby-trunk/log/20050916T140800.txt.gz
>
> ふむ。
>
> |test/socket/test_tcp.rb の変更の
> |http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/test/socket/test_tcp.rb?r1=1.6;r2=1.7
> |は p が入っていて怪しげなんですが、意図された変更でしょうか?
>
> pが入っているのは確かに怪しげなんですが、それ以外の変更
>
>   * Thread.passの追加([ruby-dev:24705]にはある)

ふむ。これは重要ですね。

>   * 0x1000から0x10000への変更(この数字が違っていてはテストの
>     意味がない)

こっちは 0x1000 であっても良いと思います。

% ruby-1.8.1 -rsocket -e '
    c = s = nil
    svr = TCPServer.new("localhost", 0)
    th = Thread.new {
      c = svr.accept
      Thread.pass
      ObjectSpace.each_object(String) {|s|
        s.replace "a" if s.length == 0x10000 and !s.frozen?
      }
      c.print("x"*0x1000)
    }
    addr = svr.addr
    sock = TCPSocket.open(addr[2], addr[1])
    p sock.recvfrom(0x10000)
'
-e:14: [BUG] Segmentation fault
ruby 1.8.1 (2003-12-25) [i686-linux]

-e:14: [BUG] Segmentation fault
ruby 1.8.1 (2003-12-25) [i686-linux]

というように、Thread.pass さえ入れれば、以前の Ruby で落ちます。

> は意図的です。なんでブロックするのかな。推測するに
>
>   * 書き換えられたので"a"しか送らない
>   * しかしrecvfrom(0x10000)が指定されたので長さが足りずブロッ
>     クした
>
> というところでしょうか。recvfrom(1)にしちゃえばいいのかな。

調べてみたところ、th.join でブロックしてます。

NetBSD では TCP のバッファに 0x10000 は入んないようで、
c.print("x"*0x10000) が終わらないので th.join も終わらないようです。

Linux でも 0x100000 にするとブロックします。
-- 
[田中 哲][たなか あきら][Tanaka Akira]