ruby-trunk-changes r33307 - r33309

今日はタイマースレッドが停止するようになった影響で IO 待ちのスレッドへの割り込みが効かなくなることがある不具合修正がありました。

nagachika:r33307 2011-09-22 02:02:21 +0900

スレッドが IO 待ちなどで GVL を解放して block するシステムコール呼び出しに入っている時に、他のスレッドから Thread#kill や Thread#raise で割り込みをしようとすると signal を飛ばしますが、実はこのしくみには race condition があって実際にシステムコールに入る前に signal を受け取ってしまうと割り込まれなくなってしまいます。そういった事態から救うために signal thread list というのが pthread 版の thread の実装にはあって、割り込まれたスレッドはこのリストに入れられて timer thread で定期的にシグナル送信されます。ところが今は timer thread は実行可能なスレッドが 2つ以上存在しない場合は定期的な polling の動作をやめてずっと待機するようになっているため、稀に signal thread list にスレッドが登録されているのに timer thread が止まってしまってこの救済策が動かない場合があって割り込みが効かなくなっていました。そこで割り込みしたら timer thread を起こすようにしています。 [ruby-core:39634] [Bug #5343]

svn:r33308 2011-09-22 02:02:32 +0900

version.h の日付更新。

nobu:r33309 2011-09-22 02:53:23 +0900

r33303 で vm_call_cfunc() の引数 reg_cfp を最適化から保護するために RB_GC_GUARD() を使っていましたが、その中身の RB_GC_GUARD_PTR() マクロを利用して、(volatile VALUE *) へのキャストを付けるようにしています。
あとコミットログに "note that `volatile type *var' doesn't make var itself volatile." て書かれていて、volatile type *var だと var が指す先が volatile であって var そのものが volatile じゃないので、type * volatile var でないといけなかったんじゃないかってことですね、多分。ただ volatile がついててもその変数が利用されなくなった位置では最適化でその変数(のメモリやレジスタ上の領域)が消される可能性はあるので RB_GC_GUARD() のようなコンパイラを騙す方法を取るほうが良いというのが最近の定説です。