7/1 に書いた組み込み Ruby とキースキャンの件のつづき。手元の PowerBook G4 (10.4) では一応動いているのに、MacBook (10.5) に持って行くと落ちまくって使い物にならない。いろいろ調べて気がついたこと(全部が今回のバグに関係あるとは限らない):
- 落ちるのは Ruby の
Thread.new
で作ったスレッドの中からnextEventMatchingMask:untilDate:inMode:dequeue:
を呼び出したとき。 - Ruby の Thread は pthread を使わず、スタックを丸ごと書き換えるという方法で実装されている。サブスレッドの中から Objective C のメソッドを呼んだ時に、システムが期待しているスタックの中身と整合性がとれなくなっているのでは?
- Ruby の Thread を使わずに、NSThread で別スレッドを立てて、そこからキースキャンをやってみた。しかし、
nextEventMatchingMask:untilDate:inMode:dequeue:
を呼んでも nil が帰ってくるだけで、イベントを取得できない。Cocoa のドキュメントには「Secondary thread の中でイベントを処理することはできる」と書いてあるのだが、どうやったらイベントを取得できるのかわからない。 - Ruby を 1.8.6 に揃えて
rb_add_event_hook()
(先日rb_set_event_hook()
と書いたのは勘違いだった)を使うことも考えたが、10.4 では Ruby.framework を自前で作って組み込むことになり、どうも気に入らない。
解決案として、Thread.new
で監視用スレッドを作るのと、実際にスクリプトを走らせるのを、同じ Objective-C 関数の中からやるようにしてみた。これなら、Ruby 側でコンテキストが切り替わっても、Objective-C に関係するスタックの中身は変わらないだろう、という読み。これでダメだったら rb_add_event_hook()
を使うしかないかなあ。
タグ: