ruby-trunk-changes r67159 - r67161

今日は Dir.glob がリソース不足で fd 開くのに失敗する時に GC で回収を試みる挙動のテストの失敗の可能性を減らす修正などがありました。

ko1: r67159 2019-03-03 09:17:18 +0900

Dir.glob で fd がプロセスの開ける fd 数上限に達した時に GC して fd の回収を試みることをチェックするテストで、後で close するために配列に IO を保存しておいて ensure で閉じるようにしてるんですけど、これだと GC されなくなっちゃうからだめなんじゃないかな。それにここは子プロセスで実行しているので。 テストが Errno::EMFILE でこけてるので setrlimit の設定がおかしいのかな…。と思ったけどよくみると open するところは最初に Errno::EMFILE が発生するぎりぎりまで実施するようにしているので、または保守的 GC なので偶然 IO が GC で回収されない状態になってしまったか、ということではないかなぁ。Enumerable#map は内部的に Array オブジェクトを作ってそこに要素を詰めていきますが、この内部的に確保された Array は途中で例外発生して抜けたら不要になりますが要素を持ったまま GC されるのを待つわけですが、たまたまこの 1つの Array が回収されなかったら、この Array に入ってる全要素も参照されていると判定されて回収されないので、このブロック内で開いた IO 全部が回収されないという悲劇が起きるのではないかなぁ。

svn: r67160 2019-03-03 09:17:21 +0900

version.h の日付更新。

ko1: r67161 2019-03-03 15:18:43 +0900

というわけで報告して r67159 のテスト再修正して、map で IO の参照を(最内の tap のブロック抜けるまでは)保持させるようにしてたのをやめて each で明示的に配列に詰めておいて、その配列を明示的に clear するようにしています。これで問題の環境でのテストも通ったようです。