aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/concurrency
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2016-02-01 23:41:07 +1030
committerMatthew Draper <matthew@trebex.net>2016-02-02 03:21:03 +1030
commitaeb58ab70470b7f395a1e77b10c9b7a73955dad8 (patch)
tree6ecf496f8abe16c56716f590087d9a8fdaeb8337 /activesupport/lib/active_support/concurrency
parent92203edbe6546f84921b6ccb6e79c3a01857a8b3 (diff)
downloadrails-aeb58ab70470b7f395a1e77b10c9b7a73955dad8.tar.gz
rails-aeb58ab70470b7f395a1e77b10c9b7a73955dad8.tar.bz2
rails-aeb58ab70470b7f395a1e77b10c9b7a73955dad8.zip
Block new share attempts if there's an exclusive waiter
Diffstat (limited to 'activesupport/lib/active_support/concurrency')
-rw-r--r--activesupport/lib/active_support/concurrency/share_lock.rb20
1 files changed, 12 insertions, 8 deletions
diff --git a/activesupport/lib/active_support/concurrency/share_lock.rb b/activesupport/lib/active_support/concurrency/share_lock.rb
index ca48164c54..1537f2898f 100644
--- a/activesupport/lib/active_support/concurrency/share_lock.rb
+++ b/activesupport/lib/active_support/concurrency/share_lock.rb
@@ -48,14 +48,14 @@ module ActiveSupport
def start_exclusive(purpose: nil, compatible: [], no_wait: false)
synchronize do
unless @exclusive_thread == Thread.current
- if busy?(purpose)
+ if busy_for_exclusive?(purpose)
return false if no_wait
loose_shares = @sharing.delete(Thread.current)
@waiting[Thread.current] = compatible if loose_shares
begin
- @cv.wait_while { busy?(purpose) }
+ @cv.wait_while { busy_for_exclusive?(purpose) }
ensure
@waiting.delete Thread.current
@sharing[Thread.current] = loose_shares if loose_shares
@@ -83,10 +83,10 @@ module ActiveSupport
end
end
- def start_sharing
+ def start_sharing(purpose: :share)
synchronize do
- if @exclusive_thread && @exclusive_thread != Thread.current
- @cv.wait_while { @exclusive_thread }
+ if busy_for_sharing?(purpose)
+ @cv.wait_while { busy_for_sharing?(purpose) }
end
@sharing[Thread.current] += 1
end
@@ -132,11 +132,15 @@ module ActiveSupport
private
# Must be called within synchronize
- def busy?(purpose)
- (@exclusive_thread && @exclusive_thread != Thread.current) ||
- @waiting.any? { |k, v| k != Thread.current && !v.include?(purpose) } ||
+ def busy_for_exclusive?(purpose)
+ busy_for_sharing?(purpose) ||
@sharing.size > (@sharing[Thread.current] > 0 ? 1 : 0)
end
+
+ def busy_for_sharing?(purpose)
+ (@exclusive_thread && @exclusive_thread != Thread.current) ||
+ @waiting.any? { |k, v| k != Thread.current && !v.include?(purpose) }
+ end
end
end
end