著作一覧 |
check_exceptionのフラグはその通りraiseさせるためのフラグです。あれは仮引数名が最低ですね。throwするかどうかのフラグでtだったり(誰もわかるはずない。でも、読めばif (t) { rb_raise(..); } だからわかるはず。で、その通り。やっぱり読めばわかる、と)。ただ、見てのとおりどの呼び出しでtを立てるかというのがいい加減(実際には、Javaに対するスクリプトからの明示的な呼び出しと例外になる可能性がある場合には立てて、rjbの内部処理でかつほとんどなければ立てないというような使い分けがある―――実際には仮引数名がどうとかよりも、こういったルールをコメントすべきですね)なのでソースからはわかりにくいと思います。
setup_については、おいおいまとめます。でも、ここについては特別なルールはなくて、淡々と初期化してるだけだからそんなに難しくはないです。ただ同じような処理が多いのでプリミティブ変換テーブルのように、処理手順をテーブル化するリファクタリングをかますかも知れません。
こちらではやはりボタン連打で(というより2回目くらいで確実に)落ちます。落ちるコードは以前Hikiのほうに貼っていただいたボタンのイベントでメッセージボックスをポップアップさせるプログラムです。mswin32とcygwinでsleep回りのライブラリの実装が違うんじゃないかな。このあたりは、確か拡張ライブラリの中でブロックを作ればしのげると思ったので(元々スタックポインタが全く異なるので無理はあるわけですが)、
Rjb::loop { break if !w.visible }というようなのと、
Rjb::signal Rjb::wait
というペアで動かすJavaのモニターを使うのの2種類くらいを用意しようかな、と考えています。
J2SE1.5でのビルド、動作確認はまだ先になると思います。
デュアルCPUだからとても死にやすいのであった。と思いついた。
イベントハンドラを処理しているスレッドがrubyのブロック(というかフレームと言うべき)を作っているときに、メイン側がsleepから戻ってブロックを巻き戻してとかやっていれば、当然のように、jumpエラーになる。なぜならjumpバッファ内のスタックポインタなどが自分が作ったものとは異なるからだ。
回避するには、
1.メイン側にはrjbの待機関数を呼び出させて、rubyのブロックが変化しないようにし、
2.ワーカスレッド側ではコールバックの最初と最後でクリティカルセクションを作って
3.クリティカルセクション内では他のスレッドの実行を待たせる
でも、こうやると、コールバックから他のスレッドと(Rubyの中で)会話しようとするとデッドロックするから考えものだったり。
本当かな?
ジェズイットを見習え |