Skip to content

Instantly share code, notes, and snippets.

@headius
Last active January 12, 2021 20:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/eb0583999cad5b3f53a14dd6a17a5e51 to your computer and use it in GitHub Desktop.
Save headius/eb0583999cad5b3f53a14dd6a17a5e51 to your computer and use it in GitHub Desktop.
require 'monitor'
Thread.report_on_exception = false
mon = Monitor.new
loop do
exit = false
locked = false
th = Thread.new do
begin
mon.synchronize { locked = true }
rescue
raise "monitor was not unlocked" if mon.mon_locked?
end
end
1 until locked
th.raise
th.join
puts :ok
end
diff --git a/lib/ruby/stdlib/monitor.rb b/lib/ruby/stdlib/monitor.rb
index 64b1f85e7c..1597ee9c40 100644
--- a/lib/ruby/stdlib/monitor.rb
+++ b/lib/ruby/stdlib/monitor.rb
@@ -230,11 +230,15 @@ module MonitorMixin
def mon_synchronize
# Prevent interrupt on handling interrupts; for example timeout errors
# it may break locking state.
- Thread.handle_interrupt(EXCEPTION_NEVER){ mon_enter }
- begin
- yield
- ensure
- Thread.handle_interrupt(EXCEPTION_NEVER){ mon_exit }
+ Thread.handle_interrupt(EXCEPTION_NEVER) do
+ mon_enter
+ begin
+ Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do
+ yield
+ end
+ ensure
+ mon_exit
+ end
end
end
alias synchronize mon_synchronize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment