[前][次][番号順一覧][スレッド一覧]

ruby-changes:30611

From: nobu <ko1@a...>
Date: Mon, 26 Aug 2013 15:27:56 +0900 (JST)
Subject: [ruby-changes:30611] nobu:r42690 (trunk): timeout.rb: skip rescue

nobu	2013-08-26 15:27:48 +0900 (Mon, 26 Aug 2013)

  New Revision: 42690

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42690

  Log:
    timeout.rb: skip rescue
    
    * lib/timeout.rb (Timeout#timeout): should not be caught by rescue
      clause.  [Bug #8730]

  Modified files:
    trunk/ChangeLog
    trunk/lib/timeout.rb
    trunk/test/test_timeout.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42689)
+++ ChangeLog	(revision 42690)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Aug 26 15:27:39 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/timeout.rb (Timeout#timeout): should not be caught by rescue
+	  clause.  [Bug #8730]
+
 Mon Aug 26 14:44:26 2013  Koichi Sasada  <ko1@a...>
 
 	* array.c (rb_ary_splice): use RARRAY_PTR_USE() without WB because
Index: lib/timeout.rb
===================================================================
--- lib/timeout.rb	(revision 42689)
+++ lib/timeout.rb	(revision 42690)
@@ -26,6 +26,18 @@ module Timeout https://github.com/ruby/ruby/blob/trunk/lib/timeout.rb#L26
   class Error < RuntimeError
   end
   class ExitException < ::Exception # :nodoc:
+    attr_reader :klass, :thread
+
+    def initialize(*)
+      super
+      @thread = Thread.current
+      freeze
+    end
+
+    def exception(*)
+      throw(self, caller) if self.thread == Thread.current
+      self
+    end
   end
 
   # :stopdoc:
@@ -50,8 +62,7 @@ module Timeout https://github.com/ruby/ruby/blob/trunk/lib/timeout.rb#L62
   # a module method, so you can call it directly as Timeout.timeout().
   def timeout(sec, klass = nil)   #:yield: +sec+
     return yield(sec) if sec == nil or sec.zero?
-    exception = klass || Class.new(ExitException)
-    begin
+    bt = catch(ExitException.new) do |exception|
       begin
         x = Thread.current
         y = Thread.start {
@@ -60,7 +71,8 @@ module Timeout https://github.com/ruby/ruby/blob/trunk/lib/timeout.rb#L71
           rescue => e
             x.raise e
           else
-            x.raise exception, "execution expired"
+            # no message, not to make new instance.
+            x.raise exception
           end
         }
         return yield(sec)
@@ -70,18 +82,14 @@ module Timeout https://github.com/ruby/ruby/blob/trunk/lib/timeout.rb#L82
           y.join # make sure y is dead.
         end
       end
-    rescue exception => e
-      rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o
-      (bt = e.backtrace).reject! {|m| rej =~ m}
-      level = -caller(CALLER_OFFSET).size
-      while THIS_FILE =~ bt[level]
-        bt.delete_at(level)
-        level += 1
-      end
-      raise if klass            # if exception class is specified, it
-                                # would be expected outside.
-      raise Error, e.message, e.backtrace
     end
+    rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o
+    bt.reject! {|m| rej =~ m}
+    level = -caller(CALLER_OFFSET).size
+    while THIS_FILE =~ bt[level]
+      bt.delete_at(level)
+    end
+    raise((klass||Error), "execution expired", bt)
   end
 
   module_function :timeout
Index: test/test_timeout.rb
===================================================================
--- test/test_timeout.rb	(revision 42689)
+++ test/test_timeout.rb	(revision 42690)
@@ -29,4 +29,18 @@ class TestTimeout < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/test_timeout.rb#L29
     def (n = Object.new).zero?; false; end
     assert_raise(TypeError, bug3168) {Timeout.timeout(n) { sleep 0.1 }}
   end
+
+  def test_skip_rescue
+    bug8730 = '[Bug #8730]'
+    e = nil
+    assert_raise(Timeout::Error, bug8730) do
+      timeout 0.1 do
+        begin
+          sleep 3
+        rescue Exception => e
+        end
+      end
+    end
+    assert_nil(e, bug8730)
+  end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]