mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Manual yield doesn't block new shares
This commit is contained in:
parent
fe7d77cc01
commit
11579b8306
1 changed files with 6 additions and 5 deletions
|
@ -45,7 +45,7 @@ module ActiveSupport
|
||||||
if busy_for_exclusive?(purpose)
|
if busy_for_exclusive?(purpose)
|
||||||
return false if no_wait
|
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) }
|
@cv.wait_while { busy_for_exclusive?(purpose) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -68,7 +68,7 @@ module ActiveSupport
|
||||||
@exclusive_thread = nil
|
@exclusive_thread = nil
|
||||||
|
|
||||||
if eligible_waiters?(compatible)
|
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) }
|
@cv.wait_while { @exclusive_thread || eligible_waiters?(compatible) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -77,7 +77,7 @@ module ActiveSupport
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def start_sharing(purpose: :share)
|
def start_sharing
|
||||||
synchronize do
|
synchronize do
|
||||||
if @sharing[Thread.current] > 0 || @exclusive_thread == Thread.current
|
if @sharing[Thread.current] > 0 || @exclusive_thread == Thread.current
|
||||||
# We already hold a lock; nothing to wait for
|
# We already hold a lock; nothing to wait for
|
||||||
|
@ -88,7 +88,7 @@ module ActiveSupport
|
||||||
else
|
else
|
||||||
# This is an initial / outermost share call: any outstanding
|
# This is an initial / outermost share call: any outstanding
|
||||||
# requests for an exclusive lock get to go first
|
# requests for an exclusive lock get to go first
|
||||||
@cv.wait_while { busy_for_sharing?(purpose) }
|
@cv.wait_while { busy_for_sharing?(false) }
|
||||||
end
|
end
|
||||||
@sharing[Thread.current] += 1
|
@sharing[Thread.current] += 1
|
||||||
end
|
end
|
||||||
|
@ -134,7 +134,7 @@ module ActiveSupport
|
||||||
# Temporarily give up all held Share locks while executing the
|
# Temporarily give up all held Share locks while executing the
|
||||||
# supplied block, allowing any +compatible+ exclusive lock request
|
# supplied block, allowing any +compatible+ exclusive lock request
|
||||||
# to proceed.
|
# to proceed.
|
||||||
def yield_shares(purpose: nil, compatible: [])
|
def yield_shares(purpose: nil, compatible: [], block_share: false)
|
||||||
loose_shares = previous_wait = nil
|
loose_shares = previous_wait = nil
|
||||||
synchronize do
|
synchronize do
|
||||||
if loose_shares = @sharing.delete(Thread.current)
|
if loose_shares = @sharing.delete(Thread.current)
|
||||||
|
@ -142,6 +142,7 @@ module ActiveSupport
|
||||||
purpose = nil unless purpose == previous_wait[0]
|
purpose = nil unless purpose == previous_wait[0]
|
||||||
compatible &= previous_wait[1]
|
compatible &= previous_wait[1]
|
||||||
end
|
end
|
||||||
|
compatible |= [false] unless block_share
|
||||||
@waiting[Thread.current] = [purpose, compatible]
|
@waiting[Thread.current] = [purpose, compatible]
|
||||||
|
|
||||||
@cv.broadcast
|
@cv.broadcast
|
||||||
|
|
Loading…
Reference in a new issue