山本です。

>(drbの仕組みをよく理解してないので、的外れかもしれません)

的外れでした。mswin32 だと、接続の閉じたソケットに書き込もうとすると Errorno::EINVAL
の例外が出て正しく実行されるのですが、bcc32 だとそのまま固まってしまうのが原因のようです。

デバッグ用に下のパッチを当てると、

Index: drb.rb
===================================================================
RCS file: /ruby/ruby/lib/drb/drb.rb,v
retrieving revision 1.19
diff -u -w -b -p -r1.19 drb.rb
--- drb.rb	16 May 2004 15:09:52 -0000	1.19
+++ drb.rb	26 May 2004 04:01:28 -0000
@@ -602,8 +602,12 @@ module DRb
     end
 
     def send_reply(stream, succ, result)  # :nodoc:
+      puts "#{Thread.current} ENTER #{succ} #{result}"
+      sleep(5)
       stream.write(dump(succ) + dump(result))
+      puts "#{Thread.current} LEAVE"
     rescue
+      puts "#{Thread.current} ERROR #{$!.class}"
       raise(DRbConnError, $!.message, $!.backtrace)
     end


Index: drbtest.rb
===================================================================
RCS file: /ruby/ruby/test/drb/drbtest.rb,v
retrieving revision 1.9
diff -u -w -b -p -r1.9 drbtest.rb
--- drbtest.rb	8 Apr 2004 11:25:24 -0000	1.9
+++ drbtest.rb	26 May 2004 03:47:05 -0000
@@ -163,9 +163,6 @@ module DRbCore
     assert_raises(TimeoutError) do
       @there.do_timeout(ten)
     end
-    assert_raises(TimeoutError) do
-      @there.do_timeout(ten)
-    end
   end
 
   def test_07_public_private


mswin32では

E:\ruby_mswin\bin>testrb -n test_06_timeout /ruby-cvs/ruby/test/drb/test_drb.rb

Loaded suite test_drb.rb
Started
#<Thread:0x2b18320> ENTER true #<DRb::ExtServManager:0x2b3c098>
#<Thread:0x2c206a8> ENTER true true
#<Thread:0x2b18320> LEAVE
#<Thread:0x2c206a8> LEAVE
#<Thread:0x2c206a8> ENTER true #<DRbEx:0x2c21338>
#<Thread:0x2c206a8> LEAVE
#<Thread:0x2c206a8> ENTER false execution expired
#<Thread:0x2b18320> ENTER true 10
#<Thread:0x2c206a8> LEAVE
#<Thread:0x2c1d6f0> ENTER true #<DRb::ExtServ:0x2c20f60>
#<Thread:0x2b18320> LEAVE
#<Thread:0x2b18320> ENTER false connection closed(閉じたソケットに書き込もうとする)
#<Thread:0x2c1d6f0> LEAVE
#<Thread:0x2b15788> ENTER true #<DRb::ExtServ:0x2c20f60>
#<Thread:0x2b18320> ERROR Errno::EINVAL(正しく失敗)
#<Thread:0x2b15788> LEAVE
#<Thread:0x2c1e0e0> ENTER true true
#<Thread:0x2b15788> ENTER false connection closed
E
Finished in 28.641 seconds.

  1) Error:
test_06_timeout(TestDRbCore):
DRb::DRbConnError: connection closed
    E:/ruby_mswin/lib/ruby/1.9/drb/drb.rb:558:in `load'
    E:/ruby_mswin/lib/ruby/1.9/drb/drb.rb:615:in `recv_reply'
    E:/ruby_mswin/lib/ruby/1.9/drb/drb.rb:869:in `recv_reply'
    E:/ruby_mswin/lib/ruby/1.9/drb/drb.rb:1105:in `send_message'
    E:/ruby_mswin/lib/ruby/1.9/drb/drb.rb:1019:in `method_missing'
    E:/ruby_mswin/lib/ruby/1.9/drb/drb.rb:1018:in `open'
    E:/ruby_mswin/lib/ruby/1.9/drb/drb.rb:1018:in `method_missing'
    E:/ruby-cvs/ruby/test/drb/drbtest.rb:75:in `teardown'

1 tests, 1 assertions, 0 failures, 1 errors

となるのに、bcc32 では

E:\ruby-cvs\ruby>.\ruby runruby.rb --ext=".ext" -- bin\testrb -n test_06_timeout
 test/drb/test_drb.rb
Loaded suite test_drb.rb
Started
#<Thread:0x2c0a6a4> ENTER true #<DRb::ExtServManager:0x2c26f04>
#<Thread:0x2c6b000> ENTER true true
#<Thread:0x2c0a6a4> LEAVE
#<Thread:0x2c6b000> LEAVE
#<Thread:0x2c6b000> ENTER true #<DRbEx:0x2c6bd98>
#<Thread:0x2c6b000> LEAVE
#<Thread:0x2c6b000> ENTER false execution expired
#<Thread:0x2c0a6a4> ENTER true 10
#<Thread:0x2c6b000> LEAVE
#<Thread:0x2c681f8> ENTER true #<DRb::ExtServ:0x2c6b9a8>
#<Thread:0x2c0a6a4> LEAVE
#<Thread:0x2c0a6a4> ENTER false connection closed (閉じたソケットに書き込もうとする)
#<Thread:0x2c681f8> LEAVE
#<Thread:0x2c07a7c> ENTER true #<DRb::ExtServ:0x2c6b9a8>
(フリーズ)

/////////////////////////////////////////////////////////////////////////////
// 修正パッチ?

bcc32, mswin32 の両方で動くようになります。

# read(0) が正しい使い方なのか、自信がありません。

Index: drb.rb
===================================================================
RCS file: /ruby/ruby/lib/drb/drb.rb,v
retrieving revision 1.19
diff -u -w -b -p -r1.19 drb.rb
--- drb.rb	16 May 2004 15:09:52 -0000	1.19
+++ drb.rb	26 May 2004 04:13:31 -0000
@@ -582,7 +582,9 @@ module DRb
 	ary.push(dump(e))
       end
       ary.push(dump(b))
+      unless stream.read(0).nil?
       stream.write(ary.join(''))
+      end
     rescue
       raise(DRbConnError, $!.message, $!.backtrace)
     end
@@ -602,7 +604,9 @@ module DRb
     end
 
     def send_reply(stream, succ, result)  # :nodoc:
+      unless stream.read(0).nil?
       stream.write(dump(succ) + dump(result))
+      end
     rescue
       raise(DRbConnError, $!.message, $!.backtrace)
     end