diff options
author | Aliaksey Kandratsenka <alk@tut.by> | 2008-10-02 21:44:49 +0300 |
---|---|---|
committer | Michael Koziarski <michael@koziarski.com> | 2008-10-04 17:48:13 +0200 |
commit | 21eb18a70c7a1f08e7e2dc1c5bc17d67e1d14c46 (patch) | |
tree | 099177cd0b202753f11001ba18d7dbf54400424b | |
parent | 4cb3d27443fa30fde528f07658e76537f38a0661 (diff) | |
download | rails-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.rb | 29 |
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 |