diff options
author | Matt Jones <al2o3cr@gmail.com> | 2014-12-23 09:54:52 -0500 |
---|---|---|
committer | Matt Jones <al2o3cr@gmail.com> | 2014-12-23 09:54:52 -0500 |
commit | 5e024070ab3766fada222053d1e0f1116aeb50a6 (patch) | |
tree | 2703a44afb53ae337eddd210323d3038ffb5baeb /tasks | |
parent | d9d865aa40b29b4b5aba71e9f6108eaab7206b1e (diff) | |
download | rails-5e024070ab3766fada222053d1e0f1116aeb50a6.tar.gz rails-5e024070ab3766fada222053d1e0f1116aeb50a6.tar.bz2 rails-5e024070ab3766fada222053d1e0f1116aeb50a6.zip |
Fix connection leak when a thread checks in additional connections.
The code in `ConnectionPool#release` assumed that a single thread only
ever holds a single connection, and thus that releasing a connection
only requires the owning thread_id.
There is a trivial counterexample to this assumption: code that checks
out additional connections from the pool in the same thread. For
instance:
connection_1 = ActiveRecord::Base.connection
connection_2 = ActiveRecord::Base.connection_pool.checkout
ActiveRecord::Base.connection_pool.checkin(connection_2)
connection_3 = ActiveRecord::Base.connection
At this point, connection_1 has been removed from the
`@reserved_connections` hash, causing a NEW connection to be returned as
connection_3 and the loss of any tracking info on connection_1. As long
as the thread in this example lives, connection_1 will be inaccessible
and un-reapable. If this block of code runs more times than the size of
the connection pool in a single thread, every subsequent connection
attempt will timeout, as all of the available connections have been
leaked.
Reverts parts of 9e457a8654fa89fe329719f88ae3679aefb21e56 and
essentially all of 4367d2f05cbeda855820e25a08353d4b7b3457ac
Diffstat (limited to 'tasks')
0 files changed, 0 insertions, 0 deletions