#同じ端末につながってる入力ポートと出力ポートがあってバッファリングしてる場合、入力が要求されたら出力バッファをフラッシュする、というのがstdioの動作なんだけど、Gaucheはstdioを使ってなくてこの仕様も実装してない。必要ならflushを入れればいいだけ、と思ってたからだけど、ちょくちょくここでつまづく人がいるので最近はやっぱり実装した方がいいと思ってる。
#一番簡単なのはアドホックに「入力ポートに出力ポートをリンクさせる」という機能をつけて、入力ポートから入力が要求されたらリンクしてる出力ポートのflushを呼ぶ、というのなんだけど、書きかけたら困ったことに気づいた。
#あるスレッドが出力中にwrite-objectメソッド内で入力を要求し、別のスレッドが同時に入力ポートから読もうとした場合にデッドロックになる可能性がある。本来同一の入力ポートから複数のスレッドが読むというのは意味の無い動作なんだけど、デバッグスタブとかでこういうことが起きないとは限らないし、その際にデッドロックしてしまうのは避けたい。
#ロックの主を調べてデッドロックの可能性があればエラーにする、というのは妥当な動作だが、入力要求の度にそれが走るのは性能的にいやな感じだ。
#なので、今は双方向ポートというのを実装しようかという気になっている。入力にも出力にも使える。ロックはそのポートに対して行われるので、出力用に誰かがロックしてたら別スレッドが読もうとするとブロックされる。
#んで、双方向ポート自体を書くのはそんなに面倒でないけど、今のScmPort構造体は双方向ポートを考えて作られておらず、バイナリ互換性のために構造体に大きく手を加えることはできない。virtual port経由なら実装できるけど入出力に一段間接呼び出しが挟まるのはやっぱり性能的にいやな感じだ。
#ってあたりまで考えて止まってたんだけど、この2ヶ月くらいでバッファリングでつっかえた例をいくつか見たので、アドホックでも何でもいいからやっちゃおうかなあ。
#ひさびさに Mac で HEAD をビルドしようとしたらエラーがこんなエラーが出ました。
#if [ . != "." ]; then ./wirebuildlibs "." "ln -s"; fi
for d in gc src lib ext doc examples; do (cd $d; /Applications/Xcode.app/Contents/Developer/usr/bin/make all) || exit 1; done
GAUCHE_LOAD_PATH="" GAUCHE_DYNLOAD_PATH="" "/Users/toru/local/gauche-head/bin/gosh" -l./preload -I../src -I../lib -I../lib geninsn ./vminsn.scm
*** ERROR: unbound variable: sis
Stack Trace:
_______________________________________
0 sis
1 (debug-source-info form)
At line 150 of "../lib/gauche/cgen/cise.scm"
2 (source-info form env)
At line 354 of "../lib/gauche/cgen/cise.scm"
3 (render-rec form env)
At line 307 of "../lib/gauche/cgen/cise.scm"
4 (call-with-output-string (cut cise-render cise <>))
At line 129 of "./geninsn"
5 (x->string (cise->string cise))
[unknown location]
6 (string-append "{" (x->string (cise->string cise)) "}")
[unknown location]
7 (cgen-body (string-append "{" (x->string (cise->string cise)) "}")
At line 134 of "./geninsn"
8 (render cise)
At line 164 of "./geninsn"
9 (render1 insn)
At line 172 of "./geninsn"
10 (do ((p insns (cdr p))) ((null? p) '()) (let1 insn (car p) (case-l
[unknown location]
11 (construct-vmbody insns)
At line 441 of "./geninsn"
make[1]: *** [gauche/vminsn.h] Error 70
make: *** [all] Error 1
#古い中間ファイルがどこかに残ってるのかな。
#あ、リリース版の Gauche を使ってないからかな。
#0.9.5 をインストールしてそっちにパスを通したらビルドできました。おさわがせしました。
#こんどは make static でエラーが……。
#$ make static
GAUCHE_LOAD_PATH="" GAUCHE_DYNLOAD_PATH="" "/Users/toru/local/gauche/bin/gosh" -l./preload -I../src -I../lib -I../lib ./gen-staticinit.scm .. ..
*** SYSTEM-ERROR: read failed on #<iport ../ext/dbm 0x101626800>: Is a directory
Stack Trace:
_______________________________________
0 (reader port)
at "../lib/gauche/portutil.scm":50
1 (file->sexp-list path)
at "././gen-staticinit.scm":135
2 (get-scm-content (cdr scmfile))
[unknown location]
3 (cgen-literal (get-scm-content (cdr scmfile)))
[unknown location]
4 (embed-scm)
at "././gen-staticinit.scm":193
5 (do-everything)
at "././gen-staticinit.scm":203
make: *** [staticinit.c] Error 70
#む。make static, linuxでも別のところで引っかかるな…