永井@知能.九工大です. From: Hidetoshi NAGAI <nagai / ai.kyutech.ac.jp> Subject: [ruby-list:41647] Re: MacOS X Aqua 対応のための tcltklib の extconf.rb Date: Sun, 4 Dec 2005 00:04:14 +0900 Message-ID: <20051204.000409.74754838.nagai / ai.kyutech.ac.jp> > > 種類の変更をしなくても繰り返すと固まりました。 念のための状況確認なのですが, 固まった状態でウィンドウの重なり順序を変えたときに, 変える前に隠れていた部分の再描画は行われるでしょうか? 再描画が行われるなら,イベントループ自体は生きていて アイドルタスクは実行されている,つまり, vwait が正常に終了していないだけということになります. 再描画が行われないなら,アイドルタスクが実行されていない, つまり,イベントループ処理がどこかでハングアップして 停止してしまっているということになります. # 多分,後者の状況であろうとは思っているのですが... その上で,tcltklib.c に添付のパッチを適用してみるとどうしょうか? このパッチはバグフィックスではありますが, 今回の問題に影響する可能性は低いだろうと思っています. ですが可能性皆無ではないので,念のためのチェックです. -- 永井 秀利 (九工大 知能情報) nagai / ai.kyutech.ac.jp --- tcltklib.c.old 2005-11-18 16:17:37.000000000 +0900 +++ tcltklib.c 2005-12-04 02:06:43.000000000 +0900 @@ -1271,10 +1271,11 @@ static int -lib_eventloop_core(check_root, update_flag, check_var) +lib_eventloop_core(check_root, update_flag, check_var, interp) int check_root; int update_flag; int *check_var; + Tcl_Interp *interp; { volatile VALUE current = eventloop_thread; int found_event = 1; @@ -1324,6 +1325,11 @@ if (*check_var || !found_event) { return found_event; } + if (interp != (Tcl_Interp*)NULL + && Tcl_InterpDeleted(interp)) { + /* IP for check_var is deleted */ + return 0; + } } /* found_event = Tcl_DoOneEvent(event_flag); */ @@ -1435,6 +1441,11 @@ if (*check_var || !found_event) { return found_event; } + if (interp != (Tcl_Interp*)NULL + && Tcl_InterpDeleted(interp)) { + /* IP for check_var is deleted */ + return 0; + } } if (NIL_P(eventloop_thread) || current == eventloop_thread) { @@ -1611,6 +1622,7 @@ int check_root; int update_flag; int *check_var; + Tcl_Interp *interp; }; VALUE @@ -1623,7 +1635,8 @@ if (lib_eventloop_core(params->check_root, params->update_flag, - params->check_var)) { + params->check_var, + params->interp)) { return Qtrue; } else { return Qfalse; @@ -1711,10 +1724,11 @@ } static VALUE -lib_eventloop_launcher(check_root, update_flag, check_var) +lib_eventloop_launcher(check_root, update_flag, check_var, interp) int check_root; int update_flag; int *check_var; + Tcl_Interp *interp; { volatile VALUE parent_evloop = eventloop_thread; struct evloop_params *args = ALLOC(struct evloop_params); @@ -1745,6 +1759,7 @@ args->check_root = check_root; args->update_flag = update_flag; args->check_var = check_var; + args->interp = interp; #if 0 return rb_ensure(lib_eventloop_main, (VALUE)args, @@ -1771,7 +1786,8 @@ check_rootwidget = Qfalse; } - return lib_eventloop_launcher(RTEST(check_rootwidget), 0, (int*)NULL); + return lib_eventloop_launcher(RTEST(check_rootwidget), 0, + (int*)NULL, (Tcl_Interp*)NULL); } static VALUE @@ -1799,7 +1815,8 @@ watchdog_evloop_launcher(check_rootwidget) VALUE check_rootwidget; { - return lib_eventloop_launcher(RTEST(check_rootwidget), 0, (int*)NULL); + return lib_eventloop_launcher(RTEST(check_rootwidget), 0, + (int*)NULL, (Tcl_Interp*)NULL); } #define EVLOOP_WAKEUP_CHANCE 3 @@ -1981,8 +1998,8 @@ rb_thread_schedule(); /* start sub-eventloop */ - foundEvent = lib_eventloop_launcher(/* not check root-widget */0, 0, - q->done); + foundEvent = RTEST(lib_eventloop_launcher(/* not check root-widget */0, 0, + q->done, (Tcl_Interp*)NULL)); if (RTEST(rb_funcall(th, ID_alive_p, 0))) { rb_funcall(th, ID_kill, 0); @@ -2812,7 +2829,7 @@ /* call eventloop */ /* ret = lib_eventloop_core(0, flags, (int *)NULL);*/ /* ignore result */ - ret = lib_eventloop_launcher(0, flags, (int *)NULL); /* ignore result */ + ret = RTEST(lib_eventloop_launcher(0, flags, (int *)NULL, interp)); /* ignore result */ /* exception check */ if (!NIL_P(rbtk_pending_exception)) { @@ -3117,8 +3134,8 @@ done = 0; - foundEvent - = lib_eventloop_launcher(/* not check root-widget */0, 0, &done); + foundEvent = RTEST(lib_eventloop_launcher(/* not check root-widget */0, + 0, &done, interp)); thr_crit_bup = rb_thread_critical; rb_thread_critical = Qtrue; @@ -3394,7 +3411,7 @@ done = 0; /* lib_eventloop_core(check_rootwidget_flag, 0, &done); */ - lib_eventloop_launcher(check_rootwidget_flag, 0, &done); + lib_eventloop_launcher(check_rootwidget_flag, 0, &done, interp); thr_crit_bup = rb_thread_critical; rb_thread_critical = Qtrue; @@ -3463,7 +3480,7 @@ done = 0; /* lib_eventloop_core(check_rootwidget_flag, 0, &done); */ - lib_eventloop_launcher(check_rootwidget_flag, 0, &done); + lib_eventloop_launcher(check_rootwidget_flag, 0, &done, interp); /* exception check */ if (!NIL_P(rbtk_pending_exception)) { @@ -3560,7 +3577,7 @@ done = 0; /* lib_eventloop_core(check_rootwidget_flag, 0, &done); */ - lib_eventloop_launcher(check_rootwidget_flag, 0, &done); + lib_eventloop_launcher(check_rootwidget_flag, 0, &done, interp); /* exception check */ if (!NIL_P(rbtk_pending_exception)) {