Fix race in ConnectionPool#checkout

After releasing monitor some connection(s) may appear in pool before monitor is re-aquired.
When this happens we'll wait for connection which is already available.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
Aliaksey Kandratsenka
2008-10-02 21:44:49 +03:00
committed by Michael Koziarski
parent 4cb3d27443
commit 21eb18a70c

View File

@@ -131,21 +131,20 @@ module ActiveRecord
# Check-out a database connection from the pool.
def checkout
# Checkout an available connection
conn = @connection_mutex.synchronize do
if @checked_out.size < @connections.size
checkout_existing_connection
elsif @connections.size < @size
checkout_new_connection
end
end
return conn if conn
# No connections available; wait for one
@connection_mutex.synchronize do
if @queue.wait(@timeout)
checkout_existing_connection
else
raise ConnectionTimeoutError, "could not obtain a database connection within #{@timeout} seconds. The pool size is currently #{@size}, perhaps you need to increase it?"
loop do
conn = if @checked_out.size < @connections.size
checkout_existing_connection
elsif @connections.size < @size
checkout_new_connection
end
return conn if conn
# No connections available; wait for one
if @queue.wait(@timeout)
next
else
raise ConnectionTimeoutError, "could not obtain a database connection within #{@timeout} seconds. The pool size is currently #{@size}, perhaps you need to increase it?"
end
end
end
end
@@ -275,4 +274,4 @@ module ActiveRecord
end
end
end
end
end