aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAliaksey Kandratsenka <alk@tut.by>2008-10-02 21:44:49 +0300
committerMichael Koziarski <michael@koziarski.com>2008-10-04 17:48:13 +0200
commit21eb18a70c7a1f08e7e2dc1c5bc17d67e1d14c46 (patch)
tree099177cd0b202753f11001ba18d7dbf54400424b
parent4cb3d27443fa30fde528f07658e76537f38a0661 (diff)
downloadrails-21eb18a70c7a1f08e7e2dc1c5bc17d67e1d14c46.tar.gz
rails-21eb18a70c7a1f08e7e2dc1c5bc17d67e1d14c46.tar.bz2
rails-21eb18a70c7a1f08e7e2dc1c5bc17d67e1d14c46.zip
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>
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb29
1 files changed, 14 insertions, 15 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 54a39db1eb..74381437ca 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -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 \ No newline at end of file
+end