From 30b7855f75f9f88e808f76091b28b9a9c947cbc5 Mon Sep 17 00:00:00 2001 From: nagai Date: Fri, 10 Dec 2010 20:58:10 +0000 Subject: * ext/tk/lib/multi-tk.rb: infinite loop on method_missing at loading. [ruby-dev:42716] [Ruby 1.9-Bug#4129] * ext/tk/lib/multi-tk.rb: when no eventloop is running, ruby freezes at exit. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30169 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/tk/lib/multi-tk.rb | 130 +++++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 58 deletions(-) (limited to 'ext') diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb index dc8a31e2e8..efeaf9830a 100644 --- a/ext/tk/lib/multi-tk.rb +++ b/ext/tk/lib/multi-tk.rb @@ -39,64 +39,6 @@ class << TclTkIp end -################################################ -# use pseudo-toplevel feature of MultiTkIp ? -if (!defined?(Use_PseudoToplevel_Feature_of_MultiTkIp) || - Use_PseudoToplevel_Feature_of_MultiTkIp) - module MultiTkIp_PseudoToplevel_Evaluable - #def pseudo_toplevel_eval(body = Proc.new) - # Thread.current[:TOPLEVEL] = self - # begin - # body.call - # ensure - # Thread.current[:TOPLEVEL] = nil - # end - #end - - def pseudo_toplevel_evaluable? - @pseudo_toplevel_evaluable - end - - def pseudo_toplevel_evaluable=(mode) - @pseudo_toplevel_evaluable = (mode)? true: false - end - - def self.extended(mod) - mod.__send__(:extend_object, mod) - mod.instance_variable_set('@pseudo_toplevel_evaluable', true) - end - end - - class Object - alias __method_missing_alias_for_MultiTkIp__ method_missing - private :__method_missing_alias_for_MultiTkIp__ - - def method_missing(id, *args) - begin - has_top = (top = MultiTkIp.__getip.__pseudo_toplevel) && - top.respond_to?(:pseudo_toplevel_evaluable?) && - top.pseudo_toplevel_evaluable? && - top.respond_to?(id) - rescue Exception => e - has_top = false - end - - if has_top - top.__send__(id, *args) - else - __method_missing_alias_for_MultiTkIp__(id, *args) - end - end - end -else - # dummy - module MultiTkIp_PseudoToplevel_Evaluable - def pseudo_toplevel_evaluable? - false - end - end -end - ################################################ # exceptiopn to treat the return value from IP class MultiTkIp_OK < Exception @@ -841,8 +783,19 @@ class MultiTkIp Thread.pass end # INTERP_THREAD.run + raise @interp_thread[:interp] if @interp_thread[:interp].kind_of? Exception @interp = @interp_thread[:interp] + # delete the interpreter and kill the eventloop thread at exit + interp = @interp + interp_thread = @interp_thread + END{ + if interp_thread.alive? + interp.delete + interp_thread.kill + end + } + def self.mainloop(check_root = true) begin TclTkLib.set_eventloop_window_mode(true) @@ -2086,6 +2039,67 @@ class MultiTkIp end end + +################################################ +# use pseudo-toplevel feature of MultiTkIp ? +if (!defined?(Use_PseudoToplevel_Feature_of_MultiTkIp) || + Use_PseudoToplevel_Feature_of_MultiTkIp) + module MultiTkIp_PseudoToplevel_Evaluable + #def pseudo_toplevel_eval(body = Proc.new) + # Thread.current[:TOPLEVEL] = self + # begin + # body.call + # ensure + # Thread.current[:TOPLEVEL] = nil + # end + #end + + def pseudo_toplevel_evaluable? + @pseudo_toplevel_evaluable + end + + def pseudo_toplevel_evaluable=(mode) + @pseudo_toplevel_evaluable = (mode)? true: false + end + + def self.extended(mod) + mod.__send__(:extend_object, mod) + mod.instance_variable_set('@pseudo_toplevel_evaluable', true) + end + end + + class Object + alias __method_missing_alias_for_MultiTkIp__ method_missing + private :__method_missing_alias_for_MultiTkIp__ + + def method_missing(id, *args) + begin + has_top = (top = MultiTkIp.__getip.__pseudo_toplevel) && + top.respond_to?(:pseudo_toplevel_evaluable?) && + top.pseudo_toplevel_evaluable? && + top.respond_to?(id) + rescue Exception => e + has_top = false + end + + if has_top + top.__send__(id, *args) + else + __method_missing_alias_for_MultiTkIp__(id, *args) + end + end + end +else + # dummy + module MultiTkIp_PseudoToplevel_Evaluable + def pseudo_toplevel_evaluable? + false + end + end +end + + +################################################ # evaluate a procedure on the proper interpreter class MultiTkIp # instance & class method -- cgit v1.2.3