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

ruby-changes:57289

From: usa <ko1@a...>
Date: Tue, 27 Aug 2019 02:04:02 +0900 (JST)
Subject: [ruby-changes:57289] usa: 4d9c58752a (ruby_2_5): merge revision(s) f91879a7b548284c93743168acfd11e3d2aeefac,9557069299ac3b96691040a541afa65761a724ad: [Backport #15992]

https://git.ruby-lang.org/ruby.git/commit/?id=4d9c58752a

From 4d9c58752a1d83be10811d4929c809a60eefeff8 Mon Sep 17 00:00:00 2001
From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Mon, 26 Aug 2019 17:03:41 +0000
Subject: merge revision(s)
 f91879a7b548284c93743168acfd11e3d2aeefac,9557069299ac3b96691040a541afa65761a724ad:
 [Backport #15992]

	handle_interrupt to defend monitor state [Bug #15992]

	If an exception is raised from another thread for example Timeout
	and this thread is just after `mon_exit`'s `@mon_owner = nil`,
	the exception breaks the state of MonitorMixin. To prevent that situation,
	it need to block interruption in mon_enter and mon_exit.

	Avoid creating Hash objects per each mon_synchronize call (#2393)


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@67774 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

diff --git a/lib/monitor.rb b/lib/monitor.rb
index 288ed75..e99cbd4 100644
--- a/lib/monitor.rb
+++ b/lib/monitor.rb
@@ -87,6 +87,9 @@ https://github.com/ruby/ruby/blob/trunk/lib/monitor.rb#L87
 # MonitorMixin module.
 #
 module MonitorMixin
+  EXCEPTION_NEVER = {Exception => :never}.freeze
+  EXCEPTION_IMMEDIATE = {Exception => :immediate}.freeze
+
   #
   # FIXME: This isn't documented in Nutshell.
   #
@@ -103,13 +106,17 @@ module MonitorMixin https://github.com/ruby/ruby/blob/trunk/lib/monitor.rb#L106
     # even if no other thread doesn't signal.
     #
     def wait(timeout = nil)
-      @monitor.__send__(:mon_check_owner)
-      count = @monitor.__send__(:mon_exit_for_cond)
-      begin
-        @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
-        return true
-      ensure
-        @monitor.__send__(:mon_enter_for_cond, count)
+      Thread.handle_interrupt(EXCEPTION_NEVER) do
+        @monitor.__send__(:mon_check_owner)
+        count = @monitor.__send__(:mon_exit_for_cond)
+        begin
+          Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do
+            @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
+          end
+          return true
+        ensure
+          @monitor.__send__(:mon_enter_for_cond, count)
+        end
       end
     end
 
@@ -221,11 +228,13 @@ module MonitorMixin https://github.com/ruby/ruby/blob/trunk/lib/monitor.rb#L228
   # +MonitorMixin+.
   #
   def mon_synchronize
-    mon_enter
+    # Prevent interrupt on handling interrupts; for example timeout errors
+    # it may break locking state.
+    Thread.handle_interrupt(Exception => :never){ mon_enter }
     begin
       yield
     ensure
-      mon_exit
+      Thread.handle_interrupt(EXCEPTION_NEVER){ mon_exit }
     end
   end
   alias synchronize mon_synchronize
diff --git a/version.h b/version.h
index c0e1f14..1cb2cd8 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L1
 #define RUBY_VERSION "2.5.6"
 #define RUBY_RELEASE_DATE "2019-08-27"
-#define RUBY_PATCHLEVEL 192
+#define RUBY_PATCHLEVEL 193
 
 #define RUBY_RELEASE_YEAR 2019
 #define RUBY_RELEASE_MONTH 8
-- 
cgit v0.10.2


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

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