Port自動closeの廃止検討

以前も書いたけど( http://d.hatena.ne.jp/mjt/20110605/p2 )、nmosh運用中のGC警告(Finalization cycle involving〜)の原因となっているportの自動closeをそろそろ廃止したい。
Scheme(R6RS/R7RS)はこれを要求していないし、これに依存したスクリプトはそもそも壊れる可能性が高い。BoehmGCは、プロセスの終了時にGCが行われることを保証しないので、単純に動作が不定となる。(それ以前に、BoehmGCは保守的GCなので、オブジェクトは一定確率で回収されない。)
Chibi schemeは多少特殊で、fdが枯渇したときにGCを走らせてfdを回収する。これは要するにプログラマのミスを許容するモデルで、ポートのとじ忘れに因る問題が"自動的に"解決される。現状のnmoshは、fdの不足でGCすることは無いが、スクリプトをlong-runさせればGCは走るので部分的にこれをサポートしているといえる。
しかし、nmoshはそもそも組み込みスクリプトとして使われることが殆どなので、このモデルは良くフィットしない。要するに外部ライブラリがfdを作ると自動的に壊れる。もっとも、他所のライブラリの殆どはリソース不足時に正常に動作しないので、このようなケースをどれくらい熱心に救うかどうかは難しい。
個人的には、ヒープのGCを単純にobject leak detectorとして使って、システムリソースの開放忘れを検出することは有益だと考えている。このためのAPIをちゃんと整備する必要は有る。一部のリソースはそれを生成したスレッドでしか回収できないことが有るため、genericなcleanup handlerを用意することは難しい。BoehmGCはスレッドをサポートしていて、あるオブジェクトのdestructorは任意のスレッドから呼び出される可能性がある。
中間解として、ポートをVM付のオブジェクトとして、VMの破棄時に処理することが考えられる。例えばRacketにはCustodianが有り( http://docs.racket-lang.org/reference/custodians.html )リソースの回収をそこに任せることが出来る。
portの自動closeは、portのbackingオブジェクトの抽出をサポートできなくなるという問題もある。つまり、port→fdのような手続きを用意したとして、このfdが外部のライブラリに渡されるようなケースを正常にハンドルする必要がある。fdのようなケースは自明で、ownerの管理も容易だが、例えばOpenGLのテクスチャのような判りづらいケースもある。
ちなみに、もっと状況が悪いのはcustomポートで、customポートのcloseはScheme手続きにできるため任意のスレッドから呼ばれる可能性がある。ちゃんと試していないが、これは多分単純に壊れるだろう。nmoshの手続きオブジェクトは属VMなので他所のVMやスレッドから評価することはできない。