> ささだです. > > (2011/05/09 11:02), KOSAKI Motohiro wrote: > > こちらは理解が追いつかなかったので補足をお願いして良いですか? > > RUBY_VM_SET_INTERRUPT() がロストしたときに、後からフラグを立て直してくれる人は > > どなたでしょうか? > > ええと,set_interrupt はロストしても,定期的にスケジューラがシグナルが > 届いているかチェックしているので大丈夫だと思いました. > > > > たとえば、 thread.c#do_selectには以下のループがありますが > > > > #if defined(__CYGWIN__) || defined(_WIN32) > > (snip) > > BLOCKING_REGION({ > > do { > > result = rb_fd_select(n, read, write, except, wait); > > (snip) > > } > > } while (__th->interrupt_flag == 0); > > }, 0, 0); > > > > > > この場合、interrupt_flag が0 だと Rubyの世界に戻ってきてくれなさそうですが、 > > 大丈夫でしょうか? > > ただ,この例を見ていると大丈夫じゃないですね.なにやってんだ,これ. WIN32は ubf_select がないから、寝る側が100msに一回起きてきてポーリングチェック するんですよ。って、作者の可能性が高い人にしたり顔で解説するのってすごく かっこわるい。 ただ、このロジック全体をwin32.c に移動させたい、とか、ポーリングかっこわるいから win32.cでselectで寝るんじゃなく、WaitForMultipleObject()で寝ておいて win32用 ubf_selectでSetEventして起こしてあげるといいかも、とかそういう脱線議論は あるかも。 > > また、タイマースレッドが定期的に起こしてくれるのはメインスレッドだけなので、 > > サブスレッドはRUBY_VM_CHECK_INTS() がfalseを返し続ける限り、 > > rb_threadptr_execute_interrupts_rec() まで来ないのではないのかという疑惑が > > あるのですが、どのルートで担保されてますでしょうか? > > あれ,そうだったっけ>メインスレッドだけ.そんなことないような. いや、あの。補足をお願いして良いですか。の返事がこれだとESP能力を 要求されてる感じです。ボスケテ static void timer_thread_function(void *arg) { rb_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */ /* for time slice */ RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread); /* check signal */ rb_threadptr_check_signal(vm->main_thread); void rb_threadptr_check_signal(rb_thread_t *mth) { int sig; /* mth must be main_thread */ if (!mth->exec_signal && (sig = rb_get_next_signal()) > 0) { enum rb_thread_status prev_status = mth->status; thread_debug("main_thread: %s, sig: %d\n", thread_status_name(prev_status), sig); mth->exec_signal = sig; if (mth->status != THREAD_KILLED) mth->status = THREAD_RUNNABLE; rb_threadptr_interrupt(mth); mth->status = prev_status; } } なので、メインスレッドが定期的に rb_threadptr_interrupt()呼ばれてるのは 自明なんですが、他のスレッドはどこからでしょうか?