ruby-trunk-changes r30843 - r30852

本日は Yokohama.rb #5 の会場から更新です。
昨日追加された --gem オプションの enabled/disabled という引数を特別な用途に予約する仕様追加、Test::Unit の修正の他に、Thread が IO 待ちをする時の処理に変更がありました。公開 API にも追加があるので拡張ライブラリ作者は要チェックです。

akr:r30843 2011-02-11 23:17:24 +0900

ext/dl/cfunc.c の関数マクロの引数にかっこをつける修正です。

yugui:r30844 2011-02-12 00:03:51 +0900

r30836 で --gem オプションが追加されたので --gem=enabled を --enable=gems の別名、 --gem=disabled を --disable=gems の別名にしています。なおパッケージ名がかぶらないように enabled, disabled という名前の gems パッケージは yugui さんが rubygems.com で取得しています。 https://rubygems.org/gems/enabled https://rubygems.org/gems/disabled

svn:r30845 2011-02-12 00:03:52 +0900

version.h の日付更新。

nobu:r30846 2011-02-12 01:04:08 +0900

configure --diable-rubygems でビルドされた ruby に --gem オプションをつけて起動した時は自動的に rubygems を読み込むようにしています。またコマンドラインオプションで --disable-gems で起動された時も --gem オプションが指定されると読み込む(あとに指定したほうが有効になる)ようになっているようです。

nobu:r30847 2011-02-12 08:03:21 +0900

set_trace_func のテストで method_added フックメソッドの呼び出しのチェックしていますが、テストクラス(TestSetTraceFunc)の特異クラスに Module.method_added を直接移植してこれが呼ばれるようにしています。親クラスの Test::Unit::TestCase で method_added を再定義していたりするとそっちに取られてしまうのでそれを避けているんじゃないかと思います。そのためチェック時のメソッドの定義されているモジュールも self.class に変更しています。

nobu:r30848 2011-02-12 09:30:13 +0900

Test::Unit::GlobOpition#non_options でコマンドライン引数でテストがひとつも指定されなかった時は base directory の下のテストを実行するように。

nobu:r30849 2011-02-12 14:41:02 +0900

Test::Unit::Mini というクラスを Test::Unit::Runner に改名しています。

nobu:r30850 2011-02-12 14:41:38 +0900

Test::Unit::AutoRunner#initialize 引数が渡されなかった時に default_dir を利用するように再修正しています。

nobu:r30851 2011-02-12 14:42:17 +0900

th_init2() を th_init() に改名しています。元々 th_init() と th_init2() は全く同じ処理をしていました。なんかちょっと変なメンバの初期化が入りこんでますけど、それは次の変更のがまぎれ込んでるみたいです。

nobu:r30852 2011-02-12 14:44:23 +0900

Socket からの読み込みでブロック中に他のスレッドでその Socket を close した時に例外が発生せずに待ってしまう不具合の修正ですが、より一般的に file descriptor の読み書きで block 中の Thread をその file descriptor を close する時に例外を発生させるように変更が行なわれています。 [Bug #4390] [ruby-core:35203]
rb_thread_io_blocking_region という関数を新設して、file descriptor への操作中に GIL の開放をするあいだその file descriptor を rb_thread_t の waiting_fd という新設されたメンバへ格納するようにしています。
これを利用して、file descriptor の close の時にこれまで空だった rb_thread_fd_close() でその file descriptor の操作で待っている Thread へ例外を発生させるようにしています。rb_thread_t 構造体はメンバ追加によりメモリ上の構造が変化しているので要注意。vm_core.h は非公開ヘッダですが、最近 ruby-debug19 をインストールしようとして失敗した時に、vm_core.h を参照しようとしているらしいメッセージをみたのでこっそり参照している拡張ライブラリを作成している人はチェックしてみましょう。
以下やや詳細をレビューします。vm->special_exception というのは NoMEmoryError などあらかじめ生成しておいた例外オブジェクトを使い回すためのものがいくつか用意されていて、それに今回の IOError を追加して使っています。これは使い回すことでロック取得中に新しいオブジェクト確保のため GC が走りはじめて時間がかかってしまうような自体を避けるためだそうです。
また IO で block 中の Thread へ例外を投げても systam call などから抜けないと例外処理をしませんが、block 中の Thread はその処理を中断させるための関数を th->unblock.func にセットしているので、それを呼ぶことで処理に割り込んでいます。IO 処理中の場合は ubf_select() というのが利用されていて、pthread 版の実装の場合は pthread_kill() で SIGVTALRM シグナルを送信して(多分 EINTR で)抜けるようにしています。