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:
parent
4c54b2a9a0
commit
e9020ac431
2 changed files with 27 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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|
|
||||
|
|
Loading…
Reference in a new issue