From 93987e6b36b1fb5ee0f82342e6a62c5e25070692 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Tue, 2 Jul 2024 16:21:39 -0700 Subject: [PATCH] Fix possible deadlock in the PostgreSQL specs Force the lock_timeout and table_exists? queries to use the same connection, otherwise they could use two different connections, and the table_exists? query will hang until the database default lock timeout. This deadlock in the specs could only be hit if there were 3+ available connections in the connection pool before the spec was running (1 for the lock, 1 for the lock_timeout, 1 for the table_exists). If 0-2 available connections were in the pool, then 1 would be taken by the lock, and the 2nd would be used for both the lock_timeout and table_exists?. --- spec/adapters/postgres_spec.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spec/adapters/postgres_spec.rb b/spec/adapters/postgres_spec.rb index 1239f1d32..fb0610f07 100644 --- a/spec/adapters/postgres_spec.rb +++ b/spec/adapters/postgres_spec.rb @@ -80,12 +80,16 @@ def c.exec_prepared(*); super; nil end t = [] @db[:test].lock('ACCESS EXCLUSIVE') do Thread.new do - @db.run "SET lock_timeout = 1" - t << @db.table_exists?(:test) + @db.synchronize do + @db.run "SET lock_timeout = 1" + t << @db.table_exists?(:test) + end end.join Thread.new do - @db.run "SET statement_timeout = 1" - t << @db.table_exists?(:test) + @db.synchronize do + @db.run "SET statement_timeout = 1" + t << @db.table_exists?(:test) + end end.join end t.must_equal [true, true]