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/