From de20f93f4e800b4820341b05dab23fe01f879fdf Mon Sep 17 00:00:00 2001 From: y-yagi Date: Tue, 24 Dec 2019 08:18:49 +0900 Subject: [PATCH] Merge pull request #38069 from y-yagi/make_load_interlock_aware_monitor_work_in_ruby27 Make `LoadInterlockAwareMonitor` work in Ruby 2.7 --- .../load_interlock_aware_monitor.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb b/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb index a8455c00483f7..480c34c640170 100644 --- a/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb +++ b/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb @@ -7,11 +7,29 @@ module Concurrency # A monitor that will permit dependency loading while blocked waiting for # the lock. class LoadInterlockAwareMonitor < Monitor + EXCEPTION_NEVER = { Exception => :never }.freeze + EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze + private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE + # Enters an exclusive section, but allows dependency loading while blocked def mon_enter mon_try_enter || ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super } end + + def synchronize + Thread.handle_interrupt(EXCEPTION_NEVER) do + mon_enter + + begin + Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do + yield + end + ensure + mon_exit + end + end + end end end end