diff options
author | Matthew Draper <matthew@trebex.net> | 2016-02-08 05:22:56 +1030 |
---|---|---|
committer | Matthew Draper <matthew@trebex.net> | 2016-02-08 05:30:53 +1030 |
commit | 11579b8306dd6303b306ee10c8bc9f7a4a6adea3 (patch) | |
tree | 8142737b9c40a2399305819ff863d7efb7518d30 /activesupport | |
parent | fe7d77cc01ae652a15b2c1896f677a56133bc0f1 (diff) | |
download | rails-11579b8306dd6303b306ee10c8bc9f7a4a6adea3.tar.gz rails-11579b8306dd6303b306ee10c8bc9f7a4a6adea3.tar.bz2 rails-11579b8306dd6303b306ee10c8bc9f7a4a6adea3.zip |
Manual yield doesn't block new shares
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/lib/active_support/concurrency/share_lock.rb | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/activesupport/lib/active_support/concurrency/share_lock.rb b/activesupport/lib/active_support/concurrency/share_lock.rb index ed3345d4dc..54244317e4 100644 --- a/activesupport/lib/active_support/concurrency/share_lock.rb +++ b/activesupport/lib/active_support/concurrency/share_lock.rb @@ -45,7 +45,7 @@ module ActiveSupport if busy_for_exclusive?(purpose) return false if no_wait - yield_shares(purpose: purpose, compatible: compatible) do + yield_shares(purpose: purpose, compatible: compatible, block_share: true) do @cv.wait_while { busy_for_exclusive?(purpose) } end end @@ -68,7 +68,7 @@ module ActiveSupport @exclusive_thread = nil if eligible_waiters?(compatible) - yield_shares(compatible: compatible) do + yield_shares(compatible: compatible, block_share: true) do @cv.wait_while { @exclusive_thread || eligible_waiters?(compatible) } end end @@ -77,7 +77,7 @@ module ActiveSupport end end - def start_sharing(purpose: :share) + def start_sharing synchronize do if @sharing[Thread.current] > 0 || @exclusive_thread == Thread.current # We already hold a lock; nothing to wait for @@ -88,7 +88,7 @@ module ActiveSupport else # This is an initial / outermost share call: any outstanding # requests for an exclusive lock get to go first - @cv.wait_while { busy_for_sharing?(purpose) } + @cv.wait_while { busy_for_sharing?(false) } end @sharing[Thread.current] += 1 end @@ -134,7 +134,7 @@ module ActiveSupport # Temporarily give up all held Share locks while executing the # supplied block, allowing any +compatible+ exclusive lock request # to proceed. - def yield_shares(purpose: nil, compatible: []) + def yield_shares(purpose: nil, compatible: [], block_share: false) loose_shares = previous_wait = nil synchronize do if loose_shares = @sharing.delete(Thread.current) @@ -142,6 +142,7 @@ module ActiveSupport purpose = nil unless purpose == previous_wait[0] compatible &= previous_wait[1] end + compatible |= [false] unless block_share @waiting[Thread.current] = [purpose, compatible] @cv.broadcast |