This simple test mostly results as
(1) rescue break, m.locked?: false
but sometimes I can see
(1) rescue break, m.locked?: true
m = Mutex.new
6.times do
Thread.new do
begin
m.synchronize do
puts 't1 action'
3.times do
puts '.'
sleep 0.5
end
raise 'Break'
end
rescue
puts "(1) rescue break, m.locked?: #{m.locked?}"
m.synchronize do
sleep 0.1
end
puts '(2) after m {sleep}'
sleep 0.1
puts 'rescue break 2'
end
end
sleep 0.1
t2 = Thread.new do
puts 't2 waiting for mutex'
m.synchronize do
puts '(3) t2 action'
end
end
t2.join
sleep 0.2
puts;puts;
end
I expected that inside the rescue block mutex will be always unlocked.
Environment: Ruby v2.6.3.62 (2019-04-16) [x64-mingw32]
Nobody promised that the processor would stop the world, waiting for your action :) That said, between
raise 'Break'
and
puts "(1) rescue break, m.locked?: #{m.locked?}"
there is another thread that might get the execution time and in turn lock the mutex.
Please also note, that
raise 'Break'
end
rescue
puts "(1) rescue break, m.locked?: #{m.locked?}"
is effectively the same as
end
puts "(1) rescue break, m.locked?: #{m.locked?}"
In the latter snippet, it should be clear that m
might be either locked by another thread, or not; we have it just released, so no promise.