Gauche:Windows:CtrlHandler

Gauche:Windows:CtrlHandler

Shiro(2011/06/10 21:35:05 PDT): Gauche/Windows(Mingw) でCtrl+Cイベントの ハンドラをどう扱おうか、という話。

WindowsにはUnixのように非同期プロセス間通信に使える シグナルってが無くて、プロセス間通信は原則としてイベントのやりとりで行う。 これは受け側で明示的にイベントを待ってないと受け取れないので、 Unixのシグナルのように割り込むモデルをうまく真似ることはできない。 (Cygwinはイベントでシグナルをエミュレートしてるけどものすごく面倒なことをやってる)。

なので、SchemeレベルでSIGINTのように見せかけてset-signal-handler!で処理させる、 というのは無理め。

SetConsoleCtrlHandler()でハンドラを登録しておくと、CTRL_C_EVENTとか 何種類かのコンソールイベントが来たときにハンドラが呼ばれる (デフォルトハンドラはExitProcess()を呼ぶようになっている。 WindowsコンソールアプリがCtrl-Cで中断できるのはそのためだろう)。

で、このCtrlHandlerがどういうタイミングで、ランタイムがどういう状態の時に呼ばれ、 どういう操作をしたら安全か、っていう肝心の話が、マニュアルエントリには 一切書いていないという相変わらずのMSDNクオリティなんだが、 ぐぐってみるとどうやら専用のスレッドが暗黙のうちに作られてそこでハンドラが 走るらしい。

今はまだMingw版はスレッド対応してないし、したとしても システムで勝手に作られたスレッドにはGaucheのVMがアタッチされてないので、 CtrlHandlerから直接Schemeコードを走らせるのはすぐにはできない。

いくつかアイディア。実現可能性を要検討

sasagawa?(2011/06/10 21:48:50 PDT) 早速にご検討いただいてありがとうございます。Windowsは設計のまずい部分があって厄介なようですね。

Shiro(2011/06/10 22:53:39 PDT): twitterでもリプライしましたが記録のためにこっちにも 書いておくと、プロセス/スレッド間通信をメッセージに統一して非同期割り込みを なくしたWindowsの設計は、それ自体はまずくないです。 むしろUnixのシグナルの方が厄介。あれは昔、 OSの抽象度が低くて、アプリケーションプログラマが非同期割り込みの処理を書くのも 普通だった時代の遺産じゃないですかね。 今回の問題は、Gaucheの提供する抽象化とWindowsのモデルとの間にミスマッチがある、 ということで、何が悪いってわけじゃないと思います。

More ...