]> Cypherpunks repositories - gostls13.git/commitdiff
database/sql: do not leak the connectionResetter goroutine
authorDaniel Theophanes <kardianos@gmail.com>
Mon, 13 Nov 2017 22:25:19 +0000 (14:25 -0800)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 14 Nov 2017 00:25:42 +0000 (00:25 +0000)
Before terminating the connectionResetter goroutine the connection
pool processes all of the connections on the channel to unlock the
driverConn instances so everthing can shutdown cleanly. However
the channel was never closed so the goroutine hangs on the range.
Close the channel prior to ranging over it. Also prevent additional
connections from being sent to the resetter after the connection
pool has been closed.

Fixes #22699

Change-Id: I440d2b13cbedec2e04621557f5bd0b1526933dd7
Reviewed-on: https://go-review.googlesource.com/77390
Run-TryBot: Daniel Theophanes <kardianos@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/database/sql/sql.go

index be73b5e372920f0be92d2a0f0cd890faedfa8cd7..252a0f6713c25f9b085f879f37e8cba203d69e46 100644 (file)
@@ -939,6 +939,7 @@ func (db *DB) connectionResetter(ctx context.Context) {
        for {
                select {
                case <-ctx.Done():
+                       close(db.resetterCh)
                        for dc := range db.resetterCh {
                                dc.Unlock()
                        }
@@ -1171,6 +1172,11 @@ func (db *DB) putConn(dc *driverConn, err error, resetSession bool) {
        if putConnHook != nil {
                putConnHook(db, dc)
        }
+       if db.closed {
+               // Connections do not need to be reset if they will be closed.
+               // Prevents writing to resetterCh after the DB has closed.
+               resetSession = false
+       }
        if resetSession {
                if _, resetSession = dc.ci.(driver.ResetSessioner); resetSession {
                        // Lock the driverConn here so it isn't released until