summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-12-10 20:58:10 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-12-10 20:58:10 +0000
commit30b7855f75f9f88e808f76091b28b9a9c947cbc5 (patch)
tree095caf19aa5c3182555b18888a56d3530e262e82 /ext
parentc3752248944a46ba0212de6f24cb94491869611c (diff)
* 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
Diffstat (limited to 'ext')
-rw-r--r--ext/tk/lib/multi-tk.rb130
1 files changed, 72 insertions, 58 deletions
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
@@ -40,64 +40,6 @@ 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
def self.send(thread, ret=nil)
@@ -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