orz
シグナル処理をしようとしたら、やっぱインタプリタの構造体(struct ForthInterp)をグローバル変数に置くしかないのかな。
シグナルハンドラの引数はシグナルの番号だけなので、どうしても外部変数に頼らざるを得ない。
できればインタプリタをいくつも実行するとかできればしたいなーとか思ってたけど難しいかもしれない。あんま意味ないかもしれないけど。
インタプリタいくつも作ってどうするんだと今思ったけど、スレッド対応とかも考えたプログラムのCでの作り方も覚えたいので、できればやりたい。
で、先人の知恵を借りようとシグナルを受け取った場合のメモリの解放についてGaucheはどうしてるのか調べてみた。
まずsrc/main.cを見てみると、sig_setup()というそれらしき関数を発見したので見てみる。
sigset_t setという変数のそれぞれのビットをシグナルを定義するかしないかに見立てて、全てのビットを立ててから定義しないシグナルのビットをそれぞれオフにしてる(なんで定義しないんだろう。windows対応とかのためだろうか)。
で、src/signal.cにあるScm_SetMasterSigmask()で登録したりしてる。
src/signal.cは、sigaction(2)を定義していたり、なんかWindowsのために色々頑張ってるぽい。
ググってみると、タイムリー(?)にもshiroさんの有用なコメントを発見。shiroさん曰く「Windowsのシグナル処理は完全な飾り」らしい。
次に、Scm_SetMasterSigmask()で登録されてるsig_handle()って関数見てみる。
その中では現在のVMがNULLならそのままreturn、そうでないならsignalPendingLimitって変数を越えた場合に、エラーメッセージを出力して_exit(2)する。
・・・あれ?ってことは処理はどっか別で行われてる?
でもコメントからするにvmがNULLでない場合もあるわけだし。その場合終了処理は行われないんだろうか。
そういやmalloc()とかされてもプログラム終了時にはOSによって全部freeされるとかどっかで聞いたような。うーん。
っていうかそもそもBoehm GCを使ってるんだからfreeする必要はない。
え?じゃ俺が調べた意味なんなの?もっと最初に気付かなかった俺ばかなの?しぬの?
オチなし。