ruby-trunk-changes r34033 - r34045

今日もたくさん修正がありました。Solaris でのメモリリーク修正、require のバリア処理の修正、FreeBSD でシグナル処理する時に時間がかかる現象の修正、Windows の IO のパフォーマンス改善など。

okkez:r34033 2011-12-14 01:33:15 +0900

タイマースレッドの終了時に pthread_attr_destroy() を呼び忘れていたため Solaris で fork するたびにメモリリークが発生していた不具合を修正しています。 [ruby-dev:44904] [Bug #5688]

naruse:r34034 2011-12-14 09:23:43 +0900

[ruby-core:39634] [Bug #5343] の Thread#kill などで IO 待ちに入る別の Thread に割り込んだ時にレースコンディションがあってブロックしてしまう現象のテストを追加しています。

naruse:r34035 2011-12-14 09:28:26 +0900

FreeBSD の不具合で失敗するテストの skip を FreeBSD 1-9 にしていましたが、不具合修正された FreeBSD 9.0 RC3 がリリースされたので改めて 1-8 までを skip 対象にしいます。 (関連コミット r33677, r33967, r33973)

nobu:r34036 2011-12-14 10:20:11 +0900

rb_barrier_wait() の返り値が true(取得成功)、false(失敗) だけだったのを、false (Barrier は破棄済み待っている Thread もいない)、nil (破棄済みだけどまだ待ってる Thread がいる、または再帰的に呼び出されている)と区別できるようにしています。そして load_lock() で取得失敗した時に自分が最後の Thread かどうか判定してテーブルから Barrier のエントリを削除するようにしてテーブルにゴミが残るのを防いでいます。

naruse:r34037 2011-12-14 11:26:17 +0900

r34034 で追加したテストは稀に止まるものなので 2000 回ループするようにしています。

naruse:r34038 2011-12-14 11:26:20 +0900

Thread が GVL を解放してブロックする可能性のあるシステムコールなどに入っているのを割り込みをかけて起こすための ubf_select() で、起こすための SIGVTALRM は喪失の可能性がある(GVL 解放後実際にシステムコールに入る前に受け取るかもしれない)ので、タイマースレッドが管理している起こすべきスレッドリストに入れて、タイマースレッドが寝ていた時のために rb_thread_wakeup_timer_thread() を呼ぶようにしていたのですが、FreeBSD 9 でシグナル受信時にタイマースレッドがメインスレッドに(シグナルを処理させるため)割り込みをかける時にもこれが呼ばれて、タイマースレッド自身を起こす(パイプに書き込む)のでタイマースレッドがずっとビジーループ状態になってしまうという現象が起きていたため、ubf_select() での rb_thread_wakeup_timer_thread() の呼び出しはタイマースレッド以外のスレッドから呼ばれた時だけにするようにしています。 [ruby-dev:44985] [Bug #5757]
なのですが、kosaki さんの指摘のように、シグナル処理させるためのメインスレッドへの割り込みにもレースがあるかもしれないので、タイマースレッドが polling mode をやめて無期限に止まるのを避けるようにしないといけないかもしれません。

nobu:r34039 2011-12-14 12:20:02 +0900

rb_barrier_release() と rb_barrier_destroy() もその Barrier で待っている Thread がまだ残っているかを true, false の戻り値で判定できるようにして、load_unlock() で自分が最後の Thread だったらテーブルから削除するようにしています。r34027 で修正したもののリファクタリングです。 [Bug #5754]

naruse:r34040 2011-12-14 14:42:34 +0900

test_thread_timer_and_interrupt という IO の読み込み待ちをしているプロセスに SIGQUIT を送信して止めるテストで、標準入力からの読み込みをしていたのを pipe の読み込みに変更しています。標準入力は親プロセスと共有されるので入力が読めてしまう可能性があるからでしょうか。

nobu:r34041 2011-12-14 15:28:32 +0900

1.9.3 以降 String#encode の :fallback オプションに Hash だけでなく Proc、Method など [] メソッドで置き換える文字を返せるものならなんでも受け付けるようになったことを rdoc 用コメントに反映させています。

usa:r34043 2011-12-14 19:38:12 +0900

Windows での改行コードの変換の処理を変更することで IO の速度改善しようとする変更です。 set_binary_mode_with_seek_cur() の内容を完全に理解できていないのですが、IO#read をバイト数指定で呼ばれた時はバイナリモードでの読み込みをするので、テキストモードで開かれている IO も一時的にバイナリモードで読み込みをするようにしています。またこの時に IO オブジェクトの読み込みバッファに既に取り込まれているものに改行コードがあったら(既に改行コードの変換がされているため)それを破棄してファイルポインタを巻き戻しているようです。 [ruby-core:41496] [Feature #5714]

usa:r34044 2011-12-14 20:02:00 +0900

Windows の nmake で make V=1 で実際のコマンドを省略せずに表示する機能がうまく動いていなかったので NULLCMD (なにもしないコマンド)を configure で作っていたものを common.mk で参照して ECHO1 を定義していたのを、Makefile.in や win32/Makefile.sub で直接 ECHO1 を定義するようにしています。 configure.in では NULLCMD に使えるコマンドをチェックしているのですが、win32/configure.bat は NULLCMD を作っていないので、win32/Makefile.sub では NULLCMD を参照せず直接 ":" を使って ECHO1 を定義するようにしています。 [ruby-dev:44933] [Bug #5711]

usa:r34045 2011-12-14 21:59:45 +0900

r34043 で追加したテストは Windows 環境でのみ実行されるようにしています。