こんにちは、なかむら(う)です。

In message "[ruby-dev:39039] [Bug #1872] [ruby_1_8] Kernel#system doesn't work in forked process"
    on Aug.07,2009 20:09:44, <redmine / ruby-lang.org> wrote:
> Mandriva 2009.1 (glibc-2.9-0.20081113.5.1mnb2)では再現しませんでしたが、
> Debian Ecth (libc6   2.3.6.ds1-13etch9) の環境で再現しました。
> リビジョンを遡っていくと、 r23268 以降、発生する(ことがある)ようです。
> 
>     * eval.c (rb_thread_start_timer): guard condition was inverted. [ruby-dev:38319]

r23268自体は正当な修正なので、要するに該当環境だとtimer thread
がいる時にforkするとまずいということなのでしょう。

POSIX threadはよくわからないのですが、つらつら考えてみたとこ
ろ、fork前にtimer threadを止めて、fork後に親子双方でまたtimer
threadを動かせばいいんじゃないかという気がしてきました。
手元には環境がないのでかずひこさんに以下のパッチを試してもら
ったところ、いちおう動くようになるみたいです。

わかる人や元のコードを書いた人(なかださんかな?)に発想が正しい
か考えてほしいのですが、どんなもんでしょうか...

Index: eval.c =================================================================== --- eval.c (revision 24389) +++ eval.c (working copy) @@ -12485,7 +12485,7 @@ rb_thread_start_timer() safe_mutex_lock(&time_thread.lock); if (pthread_create(&time_thread.thread, 0, thread_timer, args) == 0) { thread_init = 1; - pthread_atfork(0, 0, rb_thread_stop_timer); + pthread_atfork(rb_thread_stop_timer, rb_thread_start_timer, rb_thread_start_timer); pthread_cond_wait(&start, &time_thread.lock); } pthread_cleanup_pop(1);
それでは。 -- U.Nakamura <usa / garbagecollect.jp>