ruby-trunk-changes r32223 - r32228

今日は sleep がシグナルの割り込みで起きる挙動の変更、define_method と Proc と super() の組み合せで起きる SEGV の修正などがありました。

svn:r32224 2011-06-25 18:20:20 +0900

version.h の日付更新。

nagachika:r32225 2011-06-25 23:21:16 +0900

タイマースレッドがメインスレッドにシグナル受信の通知をする際に、不必要にメインスレッドの rb_thread_t::status を一時的に変更しているためにタイミングによってメインスレッドの status が THREAD_RUNNABLE に変化してしまうことがあったのを修正しています。 [ruby-dev:43894] [Bug #4072]

nagachika:r32226 2011-06-25 23:28:56 +0900

引数なしの sleep がシグナルの割り込みで(メインスレッドで sleep している時に限り)メソッドから返るようになっていたのを、シグナルでは返らないようにしています。 [ruby-dev:42601] [Bug #4072]
メインスレッドで sleep している時の挙動が変化してしまうことになります。しかし元の動作にも不安定なところがあって、現在 C レベルのシグナルハンドラは全てのスレッドが実行する可能性があり、Mac OS X ではシグナルで割り込まれた時に sleep の実体である pthread_cond_timedwait() が返り値0で抜けてきてしまう(spurious wakeup)。つまりメインスレッド以外でも sleep は抜ける可能性がありそれを避けるために修正しています。

nagachika:r32227 2011-06-26 00:05:37 +0900

以下のように Module#define_method にブロックを渡して定義したメソッドで作った Proc の中で super() を呼んでいると、その Proc をメソッドの外に持ち出して call すると cfp のスタックのスキャンがオーバランしてしまって SEGV するのを修正しています。 [ruby-core:37116] [Bug #4881]

class A
  def meth
  end
end
class B < A
  define_method(:meth) do
    Proc.new { super() }
  end
end

pr = B.new.meth
pr.call  #=> SEGV

本当はここでは super() で A#meth が呼ばれるのが良いのでしょうけど、[Bug #3136] の議論を見るとかなり大規模な変更をしないと他を壊さずにここを修正できないようなので、とりあえずこういう呼びかたをすると super() が NoMethodError 例外を発生させるようにしています。

svn:r32228 2011-06-26 00:05:41 +0900

version.h の日付更新。