diff options
author | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-07-10 09:52:30 +0000 |
---|---|---|
committer | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-07-10 09:52:30 +0000 |
commit | d2271cbdd18ea55851f21abd8862e5a3b6b98c9b (patch) | |
tree | a5b67350a63cf86c7f375ac60961514111817e07 /ext/tk/tcltklib.c | |
parent | a1a07fbfa1c0263cf3e51eca2bf2907a917bde5c (diff) |
* ext/tk/tcltklib.c: make SEGV risk lower at exit.
* ext/tk/lib/tk.rb: ditto.
* ext/tk/lib/multi-tk.rb: fail to call function-style methods on slave
interpreters. The strategy (MultiTkIp_PseudoToplevel_Evaluable) to
fix the problem is a little tricky. You may have to take care of
conflicting with it.
* ext/tk/lib/tk.rb: a little change for the pseudo-toplevel strategy.
* ext/tk/lib/tk/font.rb: ditto.
* ext/tk/lib/tk/msgcat.rb: ditto.
* ext/tk/lib/tkextlib/itk/incr_tk.rb: ditto.
* ext/tk/sample/demos-en/widget: fail to call function-style methods
on sample scripts. To fix it, a strategy which similar to the way
on MultiTiIp is used. Please take care when re-write and re-run a
demo script on the Widget-Demo code viewer.
* ext/tk/sample/demos-jp/widget: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10505 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tk/tcltklib.c')
-rw-r--r-- | ext/tk/tcltklib.c | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/ext/tk/tcltklib.c b/ext/tk/tcltklib.c index 2ec4233d47..5644dc98f2 100644 --- a/ext/tk/tcltklib.c +++ b/ext/tk/tcltklib.c @@ -4,7 +4,7 @@ * Oct. 24, 1997 Y. Matsumoto */ -#define TCLTKLIB_RELEASE_DATE "2006-07-03" +#define TCLTKLIB_RELEASE_DATE "2006-07-10" #include "ruby.h" #include "rubysig.h" @@ -81,6 +81,8 @@ static char *finalize_hook_name = "INTERP_FINALIZE_HOOK"; static void ip_finalize _((Tcl_Interp*)); +static int at_exit = 0; + /* for callback break & continue */ static VALUE eTkCallbackReturn; @@ -4358,6 +4360,33 @@ delete_slaves(ip) /* finalize operation */ +static VALUE +lib_mark_at_exit(self) + VALUE self; +{ + at_exit = 1; + return Qnil; +} + +static int +#if TCL_MAJOR_VERSION >= 8 +ip_null_proc(clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + Tcl_Obj *CONST argv[]; +#else /* TCL_MAJOR_VERSION < 8 */ +ip_null_proc(clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + char *argv[]; +#endif +{ + Tcl_ResetResult(interp); + return TCL_OK; +} + static void ip_finalize(ip) Tcl_Interp *ip; @@ -4403,6 +4432,29 @@ ip_finalize(ip) /* delete slaves */ delete_slaves(ip); + /* shut off some connections from Tcl-proc to Ruby */ + if (at_exit) { + /* NOTE: Only when at exit. + Because, ruby removes objects, which depends on the deleted + interpreter, on some callback operations. + It is important for GC. */ +#if TCL_MAJOR_VERSION >= 8 + Tcl_CreateObjCommand(ip, "ruby", ip_null_proc, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateObjCommand(ip, "ruby_eval", ip_null_proc, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateObjCommand(ip, "ruby_cmd", ip_null_proc, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); +#else /* TCL_MAJOR_VERSION < 8 */ + Tcl_CreateCommand(ip, "ruby", ip_null_proc, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(ip, "ruby_eval", ip_null_proc, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(ip, "ruby_cmd", ip_null_proc, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); +#endif + } + /* delete root widget */ #if 0 DUMP1("check `destroy'"); @@ -4425,7 +4477,7 @@ ip_finalize(ip) /* call finalize-hook-proc */ DUMP1("check `finalize-hook-proc'"); - if (Tcl_GetCommandInfo(ip, finalize_hook_name, &info)) { + if ( Tcl_GetCommandInfo(ip, finalize_hook_name, &info)) { DUMP2("call finalize hook proc '%s'", finalize_hook_name); ruby_debug = Qfalse; ruby_verbose = Qnil; @@ -4680,7 +4732,6 @@ ip_CallWhenDeleted(clientData, ip) rb_thread_critical = thr_crit_bup; } - /* initialize interpreter */ static VALUE ip_init(argc, argv, self) @@ -7925,6 +7976,8 @@ Init_tcltklib() /* --------------------------------------------------------------- */ + rb_define_module_function(lib, "_mark_at_exit", lib_mark_at_exit, 0); + rb_define_module_function(lib, "mainloop", lib_mainloop, -1); rb_define_module_function(lib, "mainloop_thread?", lib_evloop_thread_p, 0); @@ -8061,6 +8114,10 @@ Init_tcltklib() /* --------------------------------------------------------------- */ + rb_eval_string("at_exit{ TclTkLib._mark_at_exit }"); + + /* --------------------------------------------------------------- */ + ret = ruby_open_tcl_dll(rb_argv0 ? RSTRING(rb_argv0)->ptr : 0); switch(ret) { case TCLTK_STUBS_OK: |