aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/connection_pool_test.rb
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2018-08-24 01:42:22 +0930
committerGitHub <noreply@github.com>2018-08-24 01:42:22 +0930
commit1f05cc58d5c098a626bdb4a43025815d3cef5bac (patch)
tree10bebb0f00ed3e5bae2962703d4f152e209d651c /activerecord/test/cases/connection_pool_test.rb
parenta0b57bbb21ce81071220bd8c6cfd8cdda342c6c6 (diff)
parent0a1ed447999d0092e8d0e86729666fc3b4577151 (diff)
downloadrails-1f05cc58d5c098a626bdb4a43025815d3cef5bac.tar.gz
rails-1f05cc58d5c098a626bdb4a43025815d3cef5bac.tar.bz2
rails-1f05cc58d5c098a626bdb4a43025815d3cef5bac.zip
Merge pull request #31696 from BrentWheeldon/bmw-connection-pool-load-deadlock
Prevent deadlocks when waiting for connection from pool.
Diffstat (limited to 'activerecord/test/cases/connection_pool_test.rb')
-rw-r--r--activerecord/test/cases/connection_pool_test.rb38
1 files changed, 38 insertions, 0 deletions
diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb
index 6aecf5fa35..06869eeab0 100644
--- a/activerecord/test/cases/connection_pool_test.rb
+++ b/activerecord/test/cases/connection_pool_test.rb
@@ -111,6 +111,44 @@ module ActiveRecord
assert_equal connection, t.join.value
end
+ def test_full_pool_blocking_shares_load_interlock
+ @pool.instance_variable_set(:@size, 1)
+
+ load_interlock_latch = Concurrent::CountDownLatch.new
+ connection_latch = Concurrent::CountDownLatch.new
+
+ able_to_get_connection = false
+ able_to_load = false
+
+ thread_with_load_interlock = Thread.new do
+ ActiveSupport::Dependencies.interlock.running do
+ load_interlock_latch.count_down
+ connection_latch.wait
+
+ @pool.with_connection do
+ able_to_get_connection = true
+ end
+ end
+ end
+
+ thread_with_last_connection = Thread.new do
+ @pool.with_connection do
+ connection_latch.count_down
+ load_interlock_latch.wait
+
+ ActiveSupport::Dependencies.interlock.loading do
+ able_to_load = true
+ end
+ end
+ end
+
+ thread_with_load_interlock.join
+ thread_with_last_connection.join
+
+ assert able_to_get_connection
+ assert able_to_load
+ end
+
def test_removing_releases_latch
cs = @pool.size.times.map { @pool.checkout }
t = Thread.new { @pool.checkout }