[PATCH] Problem with ruby 1.8.6-p36 (and p39) on Tiger

こんにちは、
バンサンです。

このメールはこの前、ruby-coreに(ruby-core:11584)英語で送ったんですけど、答えがなかったからruby-devに、今回日本語で、送ろうと思ったんです…

Mac OS Tiger(10.4)では、こういう問題があって:
% ruby -ve ‘require “timeout” ; Timeout.timeout(5) { puts df -h }’
ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-darwin8.10.1]
/usr/local/lib/ruby/1.8/timeout.rb:54: execution expired
(Timeout::Error)
from /usr/local/lib/ruby/1.8/timeout.rb:56:in `timeout’
from -e:1

patchlevel
39でも同じ問題が起こります。ですけど–disable-pthreadsをついたら、それとも1.8のブランチや1.8.6-p0では、問題は起こらないです。

もっと調べたら、済んでない関数はrb_thread_cancel_timer
(eval.c)。この関数は1.8.6-p36や-p39だけでproc_exec_v (process.h)に呼ばれてます。
そしてpthreadã‚’ä½¿ã‚ãªã„å ´åˆã€ã“ã®é–¢æ•°ãŒç©ºã£ã½ã«ãªã‚Šã¾ã™

それでrb_thread_cancel_timerで実際に何が起こるのか、そしてどうしてTiger以外のOS(Linux,
Leopard…)でどうして問題が起こらないかを調べたんです。理由がTigerのバグであるみたいです。
実際にRubyのsystem()や``を使ったら起こるのがこういうこと:
*プロセスがフォルクされて、親が興味あることをしない。でも子は以下のことをする。
*timer
threadをkillするために、rb_thread_cancel_timerが呼ばれている。だけどこのプロセスはフォルクで作られてるから、timer
threadがない(forkは子ではcurrent
thread以外全てのthreadを殺す)。それで、子の変数のtime_threadが親のthreadを参照する。このthreadがこのプロセスのthreadでないから大部分のOSではrb_thread_cancel_timerのpthread_cancelとpthread_joinの両方も失敗する。けど、Tigerではpthread_cancelが成功すてpthread_cancelãŒæ°¸é ã«å¾…ã¤ã€‚

どうしてrb_thread_cancel_timerが呼ばれたかを調べたら(ruby-dev:30581)、これは消せないと思います。でもCのforkの子から直接呼ぶのもダメです。

このメールに小さい(pthread_atforkを使ってる)パッチを添付したんです。でもこのパッチは本当に正しい直し方であるかどうか…わからないです。

Vincent I. wrote:

e$B$3$s$K$A$O!"e(B
e$B%P%s%5%s$G$9!#e(B

e$B$3$s$K$A$O!#e(B

e$B$3$N%a!<%k$O$3$NA0!"e(Bruby-coree$B$K!Je(Bruby-core:11584e$B!K1Q8l$GAw$C$?$s$G$9$1e(B
e$B$I!“Ez$($,$J$+$C$?$+$ie(B ruby-deve$B$K!”:#2sF|K\8l$G!"Aw$m$&$H;W$C$?$s$G$9!De(B

e$BJV?.DI$$IU$$$F$J$/$F$4$a$s$J$5$$!#e(Bruby-core:11584e$B$K$O5$$E$$$F$$$F!“8!F$e(B
e$B$N7k2LAw$C$F$b$i$C$?%Q%C%A$GBg>fIW$=$&$G$9!#e(B1.8.6e$B%V%i%s%A$K:NMQ$7$h$&$He(B
e$B$*$b$$$^$9!#$”$j$,$H$&$4$6$$$^$9!#e(B