diff options
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 5c986f1dcf..9a6449adc6 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; @@ -4362,6 +4364,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; @@ -4407,6 +4436,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'"); @@ -4429,7 +4481,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; @@ -4684,7 +4736,6 @@ ip_CallWhenDeleted(clientData, ip) rb_thread_critical = thr_crit_bup; } - /* initialize interpreter */ static VALUE ip_init(argc, argv, self) @@ -7929,6 +7980,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); @@ -8065,6 +8118,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: |