Gauche:シグナルキューのオーバフロー

Gauche:シグナルキューのオーバフロー

Lingrで話してて、そもそもUnix自体がシグナルの配送の回数や順序を保証してないのだから Gaucheでもそれでいいんじゃない、ってことになった。したがって以下の議論は捨て。

原理的には、Cレベルのハンドラではフラグを立てといて、VM loop内で フラグを調べて処理するものとする。VM loopが調べるまでに同じシグナルが 複数回届いても、処理は一回だけ。

但し、Cルーチンで長時間かかってる処理をどうしても中断したい場合とか あるので、実際にはシグナル毎にカウンタを設け、特定のハードリミットに 達したらScm_Abortするようにしとく。

0.8.9に入れる予定。


(obsoleted discussion)

各VMは固定長のシグナルキューを持っていて、シグナルを受けるとCレベルのシグナルハンドラがキューにシグナルを詰める。VM loopは安全なポイントでシグナルキューを検査し、空でなければ対応するSchemeレベルのシグナルハンドラを起動する。

キューが溢れた場合、Cレベルのハンドラでできることはあまりない。メモリアロケーションも出来ないので、溢れたという事実を記録しておくことくらいだ。0.8.8まではキュー溢れのケースについては考えを保留ってことで暫定コード (Scm_Warnで警告を出す) にしていたが、ホントはCレベルシグナルハンドラ中でScm_Warnを呼ぶのは安全ではない。

0.8.9に向けて、ちょっと真面目に考えてみる。

Excessive overflow

オーバフローの回数があまりに多い場合は、何らかの異常事態が起きていると 考えられる。VMに戻らずにCルーチン内で無限ループ、もしくは非常に時間を 食う処理に入っいて外から必死に中断しようとしているか、Cレベルで シグナルを自分に投げるルーチンがループしてるか。

なので、ある一定のハードリミットを超えたらScm_Abortで強制的に 落とすことにする。ハードリミットはSchemeから設定可にしておく。

Overflow handling

ハードリミットに達しないオーバフローが起きたことをVMが知った場合に どう処理すべきか。

既に情報が失われている以上、真っ当な処理方法というのは無い。 アプリによっていくつか選択肢があり得るだろう。カスタマイズできることが 望ましい。

Schemeレベルでオーバフローの事実を見せる手段としては、こんなものが 考えられる

例外は、無視とかメッセージだけ出してスルーってのがちとやりにくい。 専用のコールバックはアドホックな感じだ。 なので、疑似シグナルが使う側から見たら綺麗かなという気がする。

ただ、疑似シグナルを導入した場合、Scheme内でのイベントを伝える手段が 例外とシグナルに分散するんで、ちょっとした気持ち悪さは残る (例えば、今後また例外にすべきか疑似シグナルにすべきか迷うようなケースが 現れた場合に、どういった基準で決めて行くべきかがちょっと見えない、とか)。

実装上は<sys-sigset>の扱いが複雑化するけど、限られたAPIの中に隠せるはずだから それほど問題ではないだろうが…

More ...