While new sharers are blocked, an existing sharer remains re-entrant

This commit is contained in:
Matthew Draper 2016-02-01 23:58:36 +10:30
parent aeb58ab704
commit f02bd2a92c
2 changed files with 30 additions and 1 deletions

@ -85,7 +85,7 @@ def stop_exclusive
def start_sharing(purpose: :share)
synchronize do
if busy_for_sharing?(purpose)
if @sharing[Thread.current] == 0 && @exclusive_thread != Thread.current && busy_for_sharing?(purpose)
@cv.wait_while { busy_for_sharing?(purpose) }
end
@sharing[Thread.current] += 1

@ -241,6 +241,35 @@ def test_new_share_attempts_block_on_waiting_exclusive
end
end
def test_share_remains_reentrant_ignoring_a_waiting_exclusive
with_thread_waiting_in_lock_section(:sharing) do |sharing_thread_release_latch|
ready = Concurrent::CyclicBarrier.new(2)
attempt_reentrancy = Concurrent::CountDownLatch.new
sharer = Thread.new do
@lock.sharing do
ready.wait
attempt_reentrancy.wait
@lock.sharing {}
end
end
exclusive = Thread.new do
@lock.sharing do
ready.wait
@lock.exclusive {}
end
end
assert_threads_stuck exclusive
attempt_reentrancy.count_down
assert_threads_not_stuck sharer
assert_threads_stuck exclusive
end
end
def test_in_shared_section_incompatible_non_upgrading_threads_cannot_preempt_upgrading_threads
scratch_pad = []
scratch_pad_mutex = Mutex.new