Commit fc2eee87 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

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/11682Reviewed-by: 's avatarAndrew Gerrand <adg@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 300d9a21
...@@ -23,12 +23,17 @@ import ( ...@@ -23,12 +23,17 @@ import (
"sync/atomic" "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. // Register makes a database driver available by the provided name.
// If Register is called twice with the same name or if driver is nil, // If Register is called twice with the same name or if driver is nil,
// it panics. // it panics.
func Register(name string, driver driver.Driver) { func Register(name string, driver driver.Driver) {
driversMu.Lock()
defer driversMu.Unlock()
if driver == nil { if driver == nil {
panic("sql: Register driver is nil") panic("sql: Register driver is nil")
} }
...@@ -39,12 +44,16 @@ func Register(name string, driver driver.Driver) { ...@@ -39,12 +44,16 @@ func Register(name string, driver driver.Driver) {
} }
func unregisterAllDrivers() { func unregisterAllDrivers() {
driversMu.Lock()
defer driversMu.Unlock()
// For tests. // For tests.
drivers = make(map[string]driver.Driver) drivers = make(map[string]driver.Driver)
} }
// Drivers returns a sorted list of the names of the registered drivers. // Drivers returns a sorted list of the names of the registered drivers.
func Drivers() []string { func Drivers() []string {
driversMu.Lock()
defer driversMu.Unlock()
var list []string var list []string
for name := range drivers { for name := range drivers {
list = append(list, name) list = append(list, name)
...@@ -457,7 +466,9 @@ var connectionRequestQueueSize = 1000000 ...@@ -457,7 +466,9 @@ var connectionRequestQueueSize = 1000000
// function should be called just once. It is rarely necessary to // function should be called just once. It is rarely necessary to
// close a DB. // close a DB.
func Open(driverName, dataSourceName string) (*DB, error) { func Open(driverName, dataSourceName string) (*DB, error) {
driversMu.Lock()
driveri, ok := drivers[driverName] driveri, ok := drivers[driverName]
driversMu.Unlock()
if !ok { if !ok {
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName) return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment