From: Yusuke Endoh Date: 2008-12-27T19:49:39+09:00 Subject: [ruby-dev:37625] [Bug #935] child process forked from child thread does not call ruby_cleanup Bug #935: child process forked from child thread does not call ruby_cleanup http://redmine.ruby-lang.org/issues/show/935 起票者: Yusuke Endoh ステータス: Open, 優先度: Normal [ruby-dev:37624] と完全に同一の内容ですが、redmine に登録し忘れたので 再送します。すみません。 ----- 遠藤です。 [ruby-dev:37447] を調べていて気がついたことですが、 子スレッドの中で fork したプロセスが ruby_cleanup をしません。 $ ./miniruby -e ' at_exit { p [:exit, $$] } Thread.new { p [fork ? :parent : :child, $$] } sleep 1 ' [:parent, 14543] [:child, 14546] [:exit, 14543] 1.8 であれば、上の例で [:exit, 14546] も表示されます。 at_exit が実行されない以外に、タイマースレッドだけ生き残ってプロセスが 終了しないとか、(おそらく) IO のファイナライザが呼び出されないとか、 いろいろと問題がある気がします。 末尾のパッチで、fork によってメインスレッドに昇格したスレッドの終了時に ruby_cleanup(state) を呼ぶようになります。が、いろいろと副作用がありそうで 怖いです。 また、うちの環境 (Debian/lenny 32bit) では現在このパッチをあてなくても make test-all で SEGV したり固まったりするので、ちゃんとテストできても ないです。 どうしたもんでしょう。 Index: thread.c =================================================================== --- thread.c (revision 21097) +++ thread.c (working copy) @@ -427,6 +427,8 @@ } TH_POP_TAG(); + if (main_th == th) ruby_cleanup(state); + /* locking_mutex must be Qfalse */ if (th->locking_mutex != Qfalse) { rb_bug("thread_start_func_2: locking_mutex must not be set (%p:%"PRIxVALUE")", @@ -440,7 +442,7 @@ } /* delete self from living_threads */ - st_delete_wrap(th->vm->living_threads, th->self); + if (main_th != th) st_delete_wrap(th->vm->living_threads, th->self); /* wake up joinning threads */ join_th = th->join_list_head; @@ -462,9 +464,6 @@ } } thread_cleanup_func(th); - if (th->vm->main_thread == th) { - rb_thread_stop_timer_thread(); - } native_mutex_unlock(&th->vm->global_vm_lock); return 0; -- Yusuke ENDOH ---------------------------------------- http://redmine.ruby-lang.org