[ruby-dev:27953] Re: 1.8.4 Preview2 検証
From:
Hidetoshi NAGAI <nagai@...>
Date:
2005-12-05 08:19:33 UTC
List:
ruby-dev #27953
永井@知能.九工大です.
From: Yukihiro Matsumoto <matz@ruby-lang.org>
Subject: [ruby-dev:27922] Re: 1.8.4 Preview2 検証
Date: Fri, 2 Dec 2005 00:25:43 +0900
Message-ID: <1133450737.002429.4354.nullmailer@x31.priv.netlab.jp>
> はい、あらかじめ宣言してあるRuby/Tkの新バージョン対応以外は
> 仕様変更は単純な追加も含めて「原則として」禁止です。バグフィッ
> クス以外のコミットは行わないでください。
Ruby/Tk に関してですが,現在 Tcl/Tk は 8.4.12rc2 です.
これまでのところ,対応が必要と思われる変更は見当たりませんので,
8.4.12 のリリース版でも大丈夫だと思います.
なお,添付の diff は,次のバグを修正するためのものです.
---------------------------------------------------------------------
・vwait や tkwait 時に,対象となっている Tk インタープリタが
delete されたにもかかわらず,vwait や tkwait の待ちを
抜け出せない恐れがある.
・vwait や tkwait 時に,スレッド切り替えや割込み処理ができなくなる.
---------------------------------------------------------------------
コミットしても構わないでしょうか?
--
永井 秀利 (九工大 知能情報)
nagai@ai.kyutech.ac.jp
--- tcltklib.c.old 2005-11-18 16:17:37.000000000 +0900
+++ tcltklib.c 2005-12-04 12:20:33.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,8 @@
int check_root;
int update_flag;
int *check_var;
+ Tcl_Interp *interp;
+ int thr_crit_bup;
};
VALUE
@@ -1623,7 +1636,8 @@
if (lib_eventloop_core(params->check_root,
params->update_flag,
- params->check_var)) {
+ params->check_var,
+ params->interp)) {
return Qtrue;
} else {
return Qfalse;
@@ -1676,6 +1690,9 @@
DUMP2("eventloop_ensure: eventloop-thread : %lx", eventloop_thread);
if (eventloop_thread != current_evloop) {
DUMP2("finish eventloop %lx (NOT current eventloop)", current_evloop);
+
+ rb_thread_critical = ptr->thr_crit_bup;
+
return Qnil;
}
@@ -1706,15 +1723,18 @@
free(ptr);
+ rb_thread_critical = ptr->thr_crit_bup;
+
DUMP2("finish current eventloop %lx", current_evloop);
return Qnil;
}
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);
@@ -1742,9 +1762,13 @@
DUMP3("tcltklib: eventloop-thread : %lx -> %lx\n",
parent_evloop, eventloop_thread);
- args->check_root = check_root;
- args->update_flag = update_flag;
- args->check_var = check_var;
+ args->check_root = check_root;
+ args->update_flag = update_flag;
+ args->check_var = check_var;
+ args->interp = interp;
+ args->thr_crit_bup = rb_thread_critical;
+
+ rb_thread_critical = Qfalse;
#if 0
return rb_ensure(lib_eventloop_main, (VALUE)args,
@@ -1771,7 +1795,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 +1824,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 +2007,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 +2838,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)) {
@@ -2995,6 +3021,24 @@
/* replace of vwait/tkwait */
/***************************/
#if TCL_MAJOR_VERSION >= 8
+static int ip_rbVwaitObjCmd _((ClientData, Tcl_Interp *, int,
+ Tcl_Obj *CONST []));
+static int ip_rb_threadVwaitObjCmd _((ClientData, Tcl_Interp *, int,
+ Tcl_Obj *CONST []));
+static int ip_rbTkWaitObjCmd _((ClientData, Tcl_Interp *, int,
+ Tcl_Obj *CONST []));
+static int ip_rb_threadTkWaitObjCmd _((ClientData, Tcl_Interp *, int,
+ Tcl_Obj *CONST []));
+#else
+static int ip_rbVwaitCommand _((ClientData, Tcl_Interp *, int, char *[]));
+static int ip_rb_threadVwaitCommand _((ClientData, Tcl_Interp *, int,
+ char *[]));
+static int ip_rbTkWaitCommand _((ClientData, Tcl_Interp *, int, char *[]));
+static int ip_rb_threadTkWaitCommand _((ClientData, Tcl_Interp *, int,
+ char *[]));
+#endif
+
+#if TCL_MAJOR_VERSION >= 8
static char *VwaitVarProc _((ClientData, Tcl_Interp *,
CONST84 char *,CONST84 char *, int));
static char *
@@ -3021,10 +3065,7 @@
return (char *) NULL;
}
-
#if TCL_MAJOR_VERSION >= 8
-static int ip_rbVwaitObjCmd _((ClientData, Tcl_Interp *, int,
- Tcl_Obj *CONST []));
static int
ip_rbVwaitObjCmd(clientData, interp, objc, objv)
ClientData clientData;
@@ -3032,7 +3073,6 @@
int objc;
Tcl_Obj *CONST objv[];
#else /* TCL_MAJOR_VERSION < 8 */
-static int ip_rbVwaitCommand _((ClientData, Tcl_Interp *, int, char *[]));
static int
ip_rbVwaitCommand(clientData, interp, objc, objv)
ClientData clientData;
@@ -3053,6 +3093,20 @@
return TCL_ERROR;
}
+#if 0
+ if (!rb_thread_alone()
+ && eventloop_thread != Qnil
+ && eventloop_thread != rb_thread_current()) {
+#if TCL_MAJOR_VERSION >= 8
+ DUMP1("call ip_rb_threadVwaitObjCmd");
+ return ip_rb_threadVwaitObjCmd(clientData, interp, objc, objv);
+#else /* TCL_MAJOR_VERSION < 8 */
+ DUMP1("call ip_rb_threadVwaitCommand");
+ return ip_rb_threadVwaitCommand(clientData, interp, objc, objv);
+#endif
+ }
+#endif
+
Tcl_Preserve(interp);
#ifdef HAVE_NATIVETHREAD
if (!is_ruby_native_thread()) {
@@ -3117,8 +3171,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;
@@ -3248,8 +3302,6 @@
}
#if TCL_MAJOR_VERSION >= 8
-static int ip_rbTkWaitObjCmd _((ClientData, Tcl_Interp *, int,
- Tcl_Obj *CONST []));
static int
ip_rbTkWaitObjCmd(clientData, interp, objc, objv)
ClientData clientData;
@@ -3257,7 +3309,6 @@
int objc;
Tcl_Obj *CONST objv[];
#else /* TCL_MAJOR_VERSION < 8 */
-static int ip_rbTkWaitCommand _((ClientData, Tcl_Interp *, int, char *[]));
static int
ip_rbTkWaitCommand(clientData, interp, objc, objv)
ClientData clientData;
@@ -3283,6 +3334,20 @@
return TCL_ERROR;
}
+#if 0
+ if (!rb_thread_alone()
+ && eventloop_thread != Qnil
+ && eventloop_thread != rb_thread_current()) {
+#if TCL_MAJOR_VERSION >= 8
+ DUMP1("call ip_rb_threadTkWaitObjCmd");
+ return ip_rb_threadTkWaitObjCmd(clientData, interp, objc, objv);
+#else /* TCL_MAJOR_VERSION < 8 */
+ DUMP1("call ip_rb_threadTkWaitCommand");
+ return ip_rb_threadTkWwaitCommand(clientData, interp, objc, objv);
+#endif
+ }
+#endif
+
Tcl_Preserve(interp);
if (objc != 3) {
@@ -3394,7 +3459,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 +3528,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 +3625,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)) {
@@ -3678,8 +3743,6 @@
}
#if TCL_MAJOR_VERSION >= 8
-static int ip_rb_threadVwaitObjCmd _((ClientData, Tcl_Interp *, int,
- Tcl_Obj *CONST []));
static int
ip_rb_threadVwaitObjCmd(clientData, interp, objc, objv)
ClientData clientData;
@@ -3687,8 +3750,6 @@
int objc;
Tcl_Obj *CONST objv[];
#else /* TCL_MAJOR_VERSION < 8 */
-static int ip_rb_threadVwaitCommand _((ClientData, Tcl_Interp *, int,
- char *[]));
static int
ip_rb_threadVwaitCommand(clientData, interp, objc, objv)
ClientData clientData;
@@ -3811,8 +3872,6 @@
}
#if TCL_MAJOR_VERSION >= 8
-static int ip_rb_threadTkWaitObjCmd _((ClientData, Tcl_Interp *, int,
- Tcl_Obj *CONST []));
static int
ip_rb_threadTkWaitObjCmd(clientData, interp, objc, objv)
ClientData clientData;
@@ -3820,8 +3879,6 @@
int objc;
Tcl_Obj *CONST objv[];
#else /* TCL_MAJOR_VERSION < 8 */
-static int ip_rb_threadTkWaitCommand _((ClientData, Tcl_Interp *, int,
- char *[]));
static int
ip_rb_threadTkWaitCommand(clientData, interp, objc, objv)
ClientData clientData;