ruby-trunk-changes r33148 - r33157

openssl で公開鍵の生成時に GVL を解放して別のスレッドが動くすようにする修正、include したモジュール内の定数を module/class 文で開いた時の挙動の修正などがありました。

naruse:r33148 2011-09-01 09:23:20 +0900

json のテストから Complex, Rational の対応のテストケースが削られています。はて、特にエラーにならず通ってたみたいですがなぜでしょう。

svn:r33149 2011-09-01 09:23:24 +0900

version.h の日付更新。

naruse:r33151 2011-09-01 09:31:18 +0900

r33147 の autoload の変更で static 関数の定義の順番の問題で未定義関数の呼び出しの警告のためビルド失敗していたのを修正。 Mac OS X だと通ってた(-Werror=implicit-function-declaration が効いてない?)ので気がつきませんでしたが Linux だとコンパイルエラーになりましたね。

usa:r33152 2011-09-01 10:22:58 +0900

r33144 の open の改行コード変換モードのテストを修正しています。puts を使うのではなくて write("\n") で改行を出力してその結果をチェックするようにしています。

usa:r33153 2011-09-01 14:09:29 +0900

Thread のテストで Module.nesting などのメソッドの Method オブジェクトをブロックのかわりに渡した場合に例外が発生するというテストが win32ole を require すると失敗するという現象のため、Windows ではこのテストを skip するようにしています。win32ole は Thread#initialize を再定義していて、そこで元来の initialize にブロックで包んで手続きを渡してしまうため、テストしたい Method オブジェクトを直接渡すという挙動ができなくなってしまうためですね。

nahi:r33155 2011-09-01 16:42:29 +0900

openssl の公開鍵ペアの生成には計算時間がかかるので、新しめの OpenSSL には途中にコールバック関数を呼ぶバージョンの生成関数が提供されていて(関数名が ??_ex で終わるもの)、それを利用して鍵生成中に GVL を解放して他の Thread が動けるようにしています。また OpenSSL::PKey::RSA/DH/DSA.new でブロックつきの呼び出しにも対応して、このコールバック関数が呼ばれる度にブロックを呼ぶこともできるようにしています。 ブロックの中で break したり raise したり(多分 throw も大丈夫)することで鍵生成を中断することもできるようになっています。
ブロック渡しの起動の時には GVL を解放せずに関数を呼んでいますが、yield する時に Thread 切り替えや割り込みチェックのチャンスがあるので、どちらにしても中断は効きます。が計算中に別のスレッドが動かないのでブロックなし版のほうがいいですね。ブロック渡しで起動しても GVL を解放して、ブロック起動するところで再度 GVL を確保するというのも原理的にはできると思うのですが、多分 GVL を解放しつつ処理を行う API はあるけど明示的に GVL を確保する API は(多分)提供されていないのでまあしかたないですね。
非同期な割り込みを使うほうがメリットがあるというのがちょっとイヤではありますが。
なおこの件はどこかのカンファレンスでPythonは鍵生成でGILを解放するのにRubyはまだしてないの? プークスクス。って言われてついカッとなって修正することになったみたいな経緯を耳にしております。 CRuby を dis るときっと CRuby はサイヤ人のように強くなっていくと思うのでみんながんばって dis ってください(建設的に)。
[追記]GVL を確保する API は rb_thread_call_with_gvl() というのがありました。GVL を確保してから渡したコールバック関数を呼んでくれるものです。例外などで抜けないようにするなど注意は必要ですけど。[/追記]

nobu:r33156 2011-09-01 17:16:29 +0900

新規追加ファイルの svn property 変更。

nobu:r33157 2011-09-01 17:31:24 +0900

Object にモジュールを include した時に、その中で定義済みのモジュール/クラスと同名のクラス/モジュールを class/module 文で再定義しようとした時に、include したモジュール内の定数とは別にトップレベルに新しい定数を定義してしまう挙動を修正しています。なんとなくチケットが違うような。この問題そのもののチケットがあったような気がするのですが見つけられませんでした。 [ruby-core:37698] [Bug #3423]
ついでに autoload のテストで eval 内で定数へ代入している部分の警告を抑制するようにしています。