From fc2eee87edd1ffbe6afd3b742760d29ac3983d3b Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 29 Jun 2015 17:56:20 -0700 Subject: [PATCH] database/sql: make Register safe for concurrent use Adding a mutex was easier than documenting it, and is consistent with gob. Fixes #9847 Change-Id: Ifa94c17e7c11643add81b35431ef840b794d78b1 Reviewed-on: https://go-review.googlesource.com/11682 Reviewed-by: Andrew Gerrand Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/database/sql/sql.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go index 96c93ed1c6..aeb5c0e382 100644 --- a/src/database/sql/sql.go +++ b/src/database/sql/sql.go @@ -23,12 +23,17 @@ import ( "sync/atomic" ) -var drivers = make(map[string]driver.Driver) +var ( + driversMu sync.Mutex + drivers = make(map[string]driver.Driver) +) // Register makes a database driver available by the provided name. // If Register is called twice with the same name or if driver is nil, // it panics. func Register(name string, driver driver.Driver) { + driversMu.Lock() + defer driversMu.Unlock() if driver == nil { panic("sql: Register driver is nil") } @@ -39,12 +44,16 @@ func Register(name string, driver driver.Driver) { } func unregisterAllDrivers() { + driversMu.Lock() + defer driversMu.Unlock() // For tests. drivers = make(map[string]driver.Driver) } // Drivers returns a sorted list of the names of the registered drivers. func Drivers() []string { + driversMu.Lock() + defer driversMu.Unlock() var list []string for name := range drivers { list = append(list, name) @@ -457,7 +466,9 @@ var connectionRequestQueueSize = 1000000 // function should be called just once. It is rarely necessary to // close a DB. func Open(driverName, dataSourceName string) (*DB, error) { + driversMu.Lock() driveri, ok := drivers[driverName] + driversMu.Unlock() if !ok { return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName) }