[ruby-list:41649] Re: MacOS X Aqua 対応のための tcltklib の extconf.rb

From: Hidetoshi NAGAI <nagai@...>
Date: 2005-12-03 18:12:38 UTC
List: ruby-list #41649
永井@知能.九工大です.

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)) {

In This Thread