From: Kazuhiro NISHIYAMA <redmine@...>
Date: 2008-10-21T16:07:45+09:00
Subject: [ruby-dev:36835] [Bug #671] TestSignal#test_exit_actionでEINTRのメッセージが出る

Bug #671: TestSignal#test_exit_actionでEINTRのメッセージが出る
http://redmine.ruby-lang.org/issues/show/671

起票者: Kazuhiro NISHIYAMA
ステータス: Open, 優先度: Normal
担当者: Kazuhiro NISHIYAMA

TestSignal#test_exit_actionの子プロセス側で
Thread.start { Thread.pass }
のスレッドが何らかの理由で終了してしまうとselectシステムコールで待たずに
readシステムコールで待つようになってしまって、以下のようになります。

Thread.start { Thread.pass }
の後にsleep 0.01などを入れると確実に再現します。

% ruby-trunk test_signal.rb -v -n test_exit_action
Loaded suite .../trunk/test/ruby/test_signal
Started
TestSignal#test_exit_action: .../trunk/test/ruby/test_signal.rb:46:in `sysread': Interrupted system call (Errno::EINTR)
        from .../trunk/test/ruby/test_signal.rb:46:in `block in test_exit_action'
        from .../trunk/test/ruby/test_signal.rb:40:in `fork'
        from .../trunk/test/ruby/test_signal.rb:40:in `test_exit_action'
        from .../lib/ruby/1.9.0/minitest/unit.rb:431:in `run'
        from .../lib/ruby/1.9.0/minitest/unit.rb:410:in `block (2 levels) in run_test_suites'
        from .../lib/ruby/1.9.0/minitest/unit.rb:404:in `each'
        from .../lib/ruby/1.9.0/minitest/unit.rb:404:in `block in run_test_suites'
        from .../lib/ruby/1.9.0/minitest/unit.rb:403:in `each'
        from .../lib/ruby/1.9.0/minitest/unit.rb:403:in `run_test_suites'
        from .../lib/ruby/1.9.0/minitest/unit.rb:383:in `run'
        from .../lib/ruby/1.9.0/minitest/unit.rb:327:in `block in autorun'
0.12 s: .

Finished in 0.119494 seconds.

1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
%


以下のようにすれば確実にスレッドが残るようになると思うのですが、
どうでしょうか?

Index: test/ruby/test_signal.rb
===================================================================
--- test/ruby/test_signal.rb	(revision 19868)
+++ test/ruby/test_signal.rb	(working copy)
@@ -41,7 +41,7 @@ class TestSignal < Test::Unit::TestCase
         Signal.trap(:USR1, "EXIT")
         w0.close
         w.syswrite("a")
-        Thread.start { Thread.pass }
+        Thread.start { sleep(2) }
         r0.sysread(4096)
       }
       r.sysread(1)


----------------------------------------
http://redmine.ruby-lang.org