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

ruby-changes:32762

From: naruse <ko1@a...>
Date: Wed, 5 Feb 2014 21:43:31 +0900 (JST)
Subject: [ruby-changes:32762] naruse:r44841 (ruby_2_1): merge revision(s) 44517, 44518, 44519, 44523: [Backport #9354]

naruse	2014-02-05 21:43:19 +0900 (Wed, 05 Feb 2014)

  New Revision: 44841

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

  Log:
    merge revision(s) 44517,44518,44519,44523: [Backport #9354]
    
    * lib/timeout.rb (Timeout#timeout): when a custom exception is given,
      no instance is needed to be caught, so defer creating new instance
      until it is raised.  [ruby-core:59511] [Bug #9354]
    
    * lib/timeout.rb (Timeout#timeout): should not rescue ordinarily
      raised ExitException, which should not be thrown.
    
    * lib/timeout.rb (Timeout::ExitException.catch): set @thread only if
      it ought to be caught.
    
    * lib/timeout.rb (Timeout::ExitException.catch): pass arguments
      for new instance.
    
    * lib/timeout.rb (Timeout::ExitException#exception): fallback to
      Timeout::Error if couldn't throw.  [ruby-dev:47872] [Bug #9380]
    
    * lib/timeout.rb (Timeout#timeout): initialize ExitException with
      message for the fallback case.

  Modified directories:
    branches/ruby_2_1/
  Modified files:
    branches/ruby_2_1/ChangeLog
    branches/ruby_2_1/lib/timeout.rb
    branches/ruby_2_1/test/test_timeout.rb
    branches/ruby_2_1/version.h
Index: ruby_2_1/ChangeLog
===================================================================
--- ruby_2_1/ChangeLog	(revision 44840)
+++ ruby_2_1/ChangeLog	(revision 44841)
@@ -1,3 +1,26 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1
+Wed Feb  5 21:12:02 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/timeout.rb (Timeout::ExitException.catch): pass arguments
+	  for new instance.
+
+	* lib/timeout.rb (Timeout::ExitException#exception): fallback to
+	  Timeout::Error if couldn't throw.  [ruby-dev:47872] [Bug #9380]
+
+	* lib/timeout.rb (Timeout#timeout): initialize ExitException with
+	  message for the fallback case.
+
+Wed Feb  5 21:12:02 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/timeout.rb (Timeout#timeout): should not rescue ordinarily
+	  raised ExitException, which should not be thrown.
+
+	* lib/timeout.rb (Timeout::ExitException.catch): set @thread only if
+	  it ought to be caught.
+
+	* lib/timeout.rb (Timeout#timeout): when a custom exception is given,
+	  no instance is needed to be caught, so defer creating new instance
+	  until it is raised.  [ruby-core:59511] [Bug #9354]
+
 Wed Feb  5 17:55:28 2014  Aman Gupta <ruby@t...>
 
 	* array.c (ary_add_hash): Fix consistency issue between Array#uniq and
Index: ruby_2_1/lib/timeout.rb
===================================================================
--- ruby_2_1/lib/timeout.rb	(revision 44840)
+++ ruby_2_1/lib/timeout.rb	(revision 44841)
@@ -26,16 +26,25 @@ module Timeout https://github.com/ruby/ruby/blob/trunk/ruby_2_1/lib/timeout.rb#L26
   class Error < RuntimeError
   end
   class ExitException < ::Exception # :nodoc:
-    attr_reader :klass, :thread
+    attr_reader :thread
 
-    def initialize(*)
-      super
-      @thread = Thread.current
-      freeze
+    def self.catch(*args)
+      exc = new(*args)
+      exc.instance_variable_set(:@thread, Thread.current)
+      exc.freeze
+      ::Kernel.catch(exc) {yield exc}
     end
 
     def exception(*)
-      throw(self, caller) if self.thread == Thread.current
+      if self.thread == Thread.current
+        bt = caller
+        begin
+          throw(self, bt)
+        rescue ArgumentError => e
+          raise unless e.message.start_with?("uncaught throw")
+          raise Error, message, backtrace
+        end
+      end
       self
     end
   end
@@ -67,7 +76,7 @@ module Timeout https://github.com/ruby/ruby/blob/trunk/ruby_2_1/lib/timeout.rb#L76
     return yield(sec) if sec == nil or sec.zero?
     message = "execution expired"
     e = Error
-    bt = catch((klass||ExitException).new) do |exception|
+    bl = proc do |exception|
       begin
         x = Thread.current
         y = Thread.start {
@@ -80,8 +89,6 @@ module Timeout https://github.com/ruby/ruby/blob/trunk/ruby_2_1/lib/timeout.rb#L89
           end
         }
         return yield(sec)
-      rescue (klass||ExitException) => e
-        e.backtrace
       ensure
         if y
           y.kill
@@ -89,6 +96,15 @@ module Timeout https://github.com/ruby/ruby/blob/trunk/ruby_2_1/lib/timeout.rb#L96
         end
       end
     end
+    if klass
+      begin
+        bl.call(klass)
+      rescue klass => e
+        bt = e.backtrace
+      end
+    else
+      bt = ExitException.catch(message, &bl)
+    end
     rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o
     bt.reject! {|m| rej =~ m}
     level = -caller(CALLER_OFFSET).size
Index: ruby_2_1/version.h
===================================================================
--- ruby_2_1/version.h	(revision 44840)
+++ ruby_2_1/version.h	(revision 44841)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1
 #define RUBY_VERSION "2.1.1"
 #define RUBY_RELEASE_DATE "2014-02-05"
-#define RUBY_PATCHLEVEL 18
+#define RUBY_PATCHLEVEL 19
 
 #define RUBY_RELEASE_YEAR 2014
 #define RUBY_RELEASE_MONTH 2
Index: ruby_2_1/test/test_timeout.rb
===================================================================
--- ruby_2_1/test/test_timeout.rb	(revision 44840)
+++ ruby_2_1/test/test_timeout.rb	(revision 44841)
@@ -57,4 +57,33 @@ class TestTimeout < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/test_timeout.rb#L57
     end
     assert_raise_with_message(exc, /execution expired/) {raise e if e}
   end
+
+  def test_custom_exception
+    bug9354 = '[ruby-core:59511] [Bug #9354]'
+    err = Class.new(StandardError) do
+      def initialize(msg) super end
+    end
+    assert_nothing_raised(ArgumentError, bug9354) do
+      assert_equal(:ok, timeout(100, err) {:ok})
+    end
+  end
+
+  def test_exit_exception
+    assert_raise_with_message(Timeout::ExitException, "boon") do
+      Timeout.timeout(10, Timeout::ExitException) do
+        raise Timeout::ExitException, "boon"
+      end
+    end
+  end
+
+  def test_enumerator_next
+    bug9380 = '[ruby-dev:47872] [Bug #9380]: timeout in Enumerator#next'
+    e = (o=Object.new).to_enum
+    def o.each
+      sleep
+    end
+    assert_raise_with_message(Timeout::Error, 'execution expired', bug9380) do
+      Timeout.timeout(0.01) {e.next}
+    end
+  end
 end

Property changes on: ruby_2_1
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r44517-44519,44523


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

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