Bug #1872

NTTレゾナントの三浦です。

Bug #1872 [ruby-dev:38996]の対策をしてみました。

■問題の復習
–enable-pthread版でruby -e 'Process.fork{p system(“ls”)}'とかすると
fork(2)の後で固まることがある。

■解析結果
・fork()でできた新しいプロセスの中にはmain thread以外のthreadは存在し
ない。当然、SIGVTALRMしてくれるthreadもいない。
・該threadの制御にsafe_mutex_lock()を使う。safe_mutex_lock()のsafeたる
所以は、lockを保持しているthreadが終了する時にlockを解放するから。そ
のためにpthread_cleanup_push()を使う。
・fork()の時には該threadが終了してはいないため、lock解放操作は行われな
い。
・fork()直後にrb_thread_stop_timer()が呼び出され、該lockを操作しようと
して刺さることがある†。


†pthread_mutex_tとpthread_mutex_lock()の実現に依存する。刺さらない環
境もあるかも。三浦が使った環境ではpthread_mutex_trylock()でも刺さる。

■対策
・fork()直後に該データを初期化する。fork()直後なので調べなくてもそうい
うthreadはいない。

ruby-1.8.7-p248だとこういうpatchでいいと思います。関数名以外は。
一晩動かしても刺さらなくなりました。