ruby-trunk-changes r51492 - r51500

今日は主に拡張ライブラリ openssl の実装の C から Ruby への一部移植や、Process.spawn で GC の mark 漏れによる SEGV の不具合の修正などがありました。

nobu: r51492 2015-08-06 02:25:35 +0900

rb_alloc_tmp_buffer()/rb_free_tmp_buffer() という、内部的な String オブジェクトのバッファを利用して、例外の発生などでメモリが回収されなくても GC で回収されるようにすることでメモリリークを防ぐ(しかし通常のケースでは明示的に解放する)関数がありますが、これを String オブジェクトではなく NODE 型のオブジェクトを利用するように書き変えています。 コミットメッセージをみると NODE_ALLOCA を利用することでバッファの内容も mark の対象にするようにしているみたいです。チケットによると Process.spawn が ALLOCV_N() を使って確保したバッファに VALUE を入れているため GC の mark 漏れが発生して SEGV するという不具合との修正みたいです。 [ruby-core:70251] [Bug #11418]
うーん VALUE の配列が欲しい時は rb_ary_tmp_new() のほうを使うのがいいんじゃないでしょうか、という気もしますね。

svn: r51493 2015-08-06 02:25:53 +0900

version.h の日付更新。

normal: r51494 2015-08-06 07:26:36 +0900

test/ruby/test_process.rb の rubyコマンドラインオプションに 256 個の引数を渡した時のテストで、子プロセスの終了を待つ timeout 値を 60 秒に延ばしています。

tenderlove: r51495 2015-08-06 07:55:38 +0900

拡張ライブラリ openssl の OpenSSL::SSL::SSLSocket#initialize の実装を C 実装から Ruby 実装に移植しています。

tenderlove: r51496 2015-08-06 07:59:00 +0900

拡張ライブラリ openssl の OpenSSL::SSL::Nonblock という Module を削除して、それを include していた OpenSSL::SSL::SSLSocket の #initialize に直接その内容を追加するリファクタリング

tenderlove: r51497 2015-08-06 08:17:33 +0900

拡張ライブラリ openssl の OpenSSL::SSL::SSLSocket#close の実装のうち OpenSSL の関数 ossl_ssl_shutdown() の呼び出しと SSL 構造体の解放の部分だけを #stop という private method に分離して、あとは Ruby 実装に移植しています。
こうしてみると openssl の実装は C で Ruby のメソッドを呼び出してごにょごにょするみたいな実装が多くて、これから徐々に Ruby 実装の部分を増やしていこうとしているんですかね。

nobu: r51498 2015-08-06 10:44:03 +0900

ruby_atomic.h に ATOMIC_VALUE_EXCHANGE() と ATOMIC_VALUE_CAS() という VALUE 型の変数に対する atomic な操作を行うマクロを追加しています。といっても size_t と VALUE サイズが異なる環境では代替実装の関数へ展開されるようになってて atomic 性は保障されてないみたいですけど。

nobu: r51499 2015-08-06 10:50:00 +0900

r51492 の rb_alloc_tmp_buffer() で T_NODE 型オブジェクトを利用するようにした変更でサイズの計算を VALUE のサイズの倍数に切り上げるようにしています。実際に確保するサイズは引数の len だったんですけど memsize_of のための u3.cnt に格納するサイズが VALUE 型のサイズの倍数に対して切り捨てになってました。

nobu: r51500 2015-08-06 10:56:37 +0900

r51492 および r51499 のさらに再修正。 rb_alloc_tmp_buffer(), rb_free_tmp_buffer() の実装を node.c からさらに gc.c に移動しています。