[#37248] [Feature:1.9] Enumerator#inspect — "Yusuke ENDOH" <mame@...>

遠藤です。

12 messages 2008/12/02

[#37337] [Feature #841] Object#self — "rubikitch ." <redmine@...>

Feature #841: Object#self

13 messages 2008/12/09

[#37513] Current status of 1.9.1 RC1's issues — "Yugui (Yuki Sonoda)" <yugui@...>

Hi, folks

14 messages 2008/12/20
[#37516] Re: Current status of 1.9.1 RC1's issues — Masatoshi SEKI <m_seki@...> 2008/12/20

咳といいます。

[#37576] [BUG:trunk] encoding for stdio's — "Yugui (Yuki Sonoda)" <yugui@...>

Yuguiです。

11 messages 2008/12/24

[ruby-dev:37427] Re: [ruby-core:20448] [Bug #727] Signal(CLD) seems not to work on OS X

From: "Yugui (Yuki Sonoda)" <yugui@...>
Date: 2008-12-13 12:43:57 UTC
List: ruby-dev #37427
Yuguiです。

[ruby-core:20448]について、いくつかのことが起こっているように思います。
まず、問題のコードを引用します。

Signal.trap(:CHLD)  { puts "Child died" }
fork && Process.wait


ところで、私の環境では例外は発生しません。ただし、Trapに渡したブロックも
実行されません。
% uname -a
                               Darwin yugui-macbook.local 9.5.0 Darwin
Kernel Version 9.5.0: Wed Sep  3 11:29:43 PDT 2008;
root:xnu-1228.7.58~1/RELEASE_I386 i386
% ./miniruby test.rb
% ./miniruby test.rb

見てみると、timer_thread_functionに制御が渡ってきている気配がありませ
ん。そこで、

diff --git a/thread_pthread.c b/thread_pthread.c
index a23e772..b8f3d4e 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -768,6 +768,7 @@ thread_timer(void *dummy)
 #endif
        timer_thread_function(dummy);
     }
+    timer_thread_function(dummy);
     native_mutex_unlock(&timer_thread_lock);
     return NULL;
 }

このようにして強制的に制御を渡してやると高い確率でChild diedが出力されま
す。しかし、ここで高い確率でErrno::EINTRも発生するようになります。

Errno::EINTRはProcess.waitが発生させています。これは結局waitpid(2)がエ
ラーを返すためのようです。そこで、添付のようなコードで実験してみると同じ
ようにwaitpidがEINTRで失敗します。これはsigaction(2)のSA_RESTARTの項に書
かれている挙動です。よって、次のようにして解決できます。


diff --git a/signal.c b/signal.c
index 91aa7c4..b393280 100644
--- a/signal.c
+++ b/signal.c
@@ -475,6 +475,9 @@ ruby_signal(int signum, sighandler_t handler)
     if (signum == SIGSEGV)
        sigact.sa_flags |= SA_ONSTACK;
 #endif
+#ifdef SA_RESTART
+    sigact.sa_flags |= SA_RESTART;
+#endif
     if (sigaction(signum, &sigact, &old) < 0) {
        if (errno != 0 && errno != EINVAL) {
            rb_bug("sigaction error.\n");



問題は2つに分かれるように思います。
(1) OSのタイミング的にはRubyプロセスに届いたシグナルがSignal.trapで処理
されないことは許されるであろうか? 許されないとすれば、スレッドの同期をど
うとる?
(VMの設計)

(2) 上の修正ではシグナルの種類によらずシステムコールを再開しているが、こ
れは望ましいか。SIGCHLDに限定した方がよい?
sleepなどはEINTRを無視して再開するように実装されているが、Rubyの
Process.waitにおいて、シグナル受信で目覚める(そしてErrno::EINTR)ことは期
待された挙動であろうか。
(言語の設計と各プラットフォームの振る舞い)

-- 
Yugui <yugui@yugui.jp>
http://yugui.jp
私は私をDumpする

In This Thread

Prev Next