rails/rails — pull request #18167 by al2o3cr (2014-12-23 15:05:00+00:00)
Title: Fix connection leak when a thread checks in additional connections.

NOTE: this is a severe app-crashing regression from 4.1.8 to 4.2.0. The fix should be trivial to backport to 4-2-stable.

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

/cc @tenderlove @matthewd @sgrif