Permalink
Browse files

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>
  • Loading branch information...
1 parent 4cb3d27 commit 21eb18a70c7a1f08e7e2dc1c5bc17d67e1d14c46 Aliaksey Kandratsenka committed with NZKoz Oct 2, 2008
Showing with 14 additions and 15 deletions.
  1. +14 −15 activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -131,21 +131,20 @@ def clear_stale_cached_connections!
# 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 @@ def retrieve_connection_pool(klass)
end
end
end
-end
+end

0 comments on commit 21eb18a

Please sign in to comment.