1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Handle thread death during lock acquisition

Specifically, clean up if the thread is killed while it's blocked
awaiting the lock... if we get killed on some other arbitrary line, the
result remains quite undefined.
This commit is contained in:
Matthew Draper 2015-07-21 11:48:21 +09:30
parent 4c54b2a9a0
commit e9020ac431
2 changed files with 27 additions and 4 deletions

View file

@ -54,10 +54,12 @@ module ActiveSupport
loose_shares = @sharing.delete(Thread.current)
@waiting[Thread.current] = compatible if loose_shares
@cv.wait_while { busy?(purpose) }
@waiting.delete Thread.current
@sharing[Thread.current] = loose_shares if loose_shares
begin
@cv.wait_while { busy?(purpose) }
ensure
@waiting.delete Thread.current
@sharing[Thread.current] = loose_shares if loose_shares
end
end
@exclusive_thread = Thread.current
end

View file

@ -81,6 +81,27 @@ class ShareLockTest < ActiveSupport::TestCase
end
end
def test_killed_thread_loses_lock
with_thread_waiting_in_lock_section(:sharing) do |sharing_thread_release_latch|
thread = Thread.new do
@lock.sharing do
@lock.exclusive {}
end
end
assert_threads_stuck thread
thread.kill
sharing_thread_release_latch.count_down
thread = Thread.new do
@lock.exclusive {}
end
assert_threads_not_stuck thread
end
end
def test_exclusive_conflicting_purpose
[true, false].each do |use_upgrading|
with_thread_waiting_in_lock_section(:sharing) do |sharing_thread_release_latch|