#read()から戻ってきてないです。
#マクロを手で展開して差し替えて確認しました。
#ありがとうございます。となるとfdの使い方が悪いとかいう話になるんだろうけれど、SOCKETハンドルから_open_osfhandleでfdを得てreadに渡すって定番の手順だから、同様の問題が他でも出てないというのが謎なんだよなあ (ぐぐり方が悪いのかもしれないが…)
##そこでもSOCKETを_open_osfhandleでinteger fdに変換すればread()に渡せるよって話になってますよね。
#あっ見逃してました。書いてありますね。うむ。
#他の言語処理系とかで似たような症状が報告されてないならGaucheの実装が何か特別なことをやってるせいだと思うんですが…
#全く動かない方の環境でもう少し調べてみました。
_get_osfhandleを通ってなさそうな感じがします。grepして、_get_osfhandle()を呼び出している3カ所(libsyssys_get_osfhandle(), Scm_FdReady(), win_prepare_handles())に、printfを入れましたが通った形跡がありません。
もう一つ、file_filler() にもprintfが入っているのですが、ハングアップする以前にも同じfd=4でfile_filler()が何度も呼ばれています。readにfd=4を与えて、readから戻ってきてます。このときは、libioread_line()もScm_ReadLine()もどちらも1回も呼ばれていません。
ハングアップする直前のfile_fillerは、libioread_line -> Scm_ReadLine -> file_fillerの順に呼ばれて、fd=4でreadを呼び出し戻ってきません。
#読みにくくなってしまった。
#本来なら、どこで_get_osfhandleを呼び出すのでしょうか。
#ソケットの場合はget_osfhandleは使わず、(1)ソケット作成時にSOCKETハンドルを得る (2)そのソケットに関するポートが最初に要求されたときにopen_osfhandleでfdを割り当て、そのfdをもとにfile portを作る (3)以降、ソケットに対するI/Oは全てこの時作られたfd経由で行われる、となります。なお、fdはクローズされたら再利用されるので、以前にfd=4で呼ばれているのがソケットとは限りません。
#open_osfhandle ですね。追ってみます。ありがとうございます。
#すいません。open_osfhandle を呼び出しているところってソースの中にありますか?system.cの中のコメント /* windows voodoo to make _open_osfhandle magic work */ しか見つかりません。
#ext/*/*.c もgrepに含めてみてください
#つか今やってみた。ext/net/net.cだけですね。使ってるのは。
#みつけました。ありがとうございます。
#入力用と出力用に、ひとつのソケットに対してopen_osfhandleは2回呼び出されるんだけど、これってwindows的にはどうだったかな。MSDNのマニュアルには例によって複数回呼び出したらどうなるか、みたいな境界条件がさっぱり書いてない。http://msdn.microsoft.com/ja-jp/library/bdts1c9x(v=vs.110).aspx #試しにこのパッチどうですか。 https://gist.github.com/3871019 open_osfhandleを1回だけ呼んで、入力出力でCRT fdを共有します。手元のMinGWでは動きました。 #ごめんなさい。今日はここまでです。
#あと、パッチの当て方も教えていただけませんか。
#$ patch < gistfile1.txt
can't find file to patch at input line 5
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/ext/net/gauche-net.h b/ext/net/gauche-net.h
|index 7377a36..07ee38a 100644
|--- a/ext/net/gauche-net.h
|+++ b/ext/net/gauche-net.h
--------------------------
#私の知ってるパッチの当て方だと上手くいかないので、git用の方法があるのでしょうか。
#メッセージに出てるように -p オプションで妥当な数字を指定すればいいと思います。
#ソースツリーの根で実行するなら -p1 かな?
##thundering herdの実験しようかと書いたんですが、もうちょっとすっきり書けないもんかなぁ、と。
#試してないけど、(call-with-client-socket s copy-port) って書けるんじゃないでしょうか。
#バッファのサイズ指定がいるなら (call-with-client-socket s (cut copy-port <> <> :size 8192)) かな。
#確かに。いけますね。
#:size じゃなくて :unit だった。
#更新しました。
#iota で作ったリストは長さが必要なだけみたいなので、 map よりも list-tabulate かなぁという気がします。
#srfi-1 の use が必要になるので全体ではそれほど差がないかな。
#list-tabulate使ったことなかった...
#更新しました。