Merge pull request #427 from otoolep/conn_stmt_race

Address data race during close database and statement
This commit is contained in:
mattn 2017-06-18 12:59:56 +09:00 committed by GitHub
commit a819994f72
1 changed files with 14 additions and 1 deletions

View File

@ -113,6 +113,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"unsafe" "unsafe"
@ -157,6 +158,7 @@ type SQLiteDriver struct {
// SQLiteConn implement sql.Conn. // SQLiteConn implement sql.Conn.
type SQLiteConn struct { type SQLiteConn struct {
dbMu sync.Mutex
db *C.sqlite3 db *C.sqlite3
loc *time.Location loc *time.Location
txlock string txlock string
@ -679,11 +681,22 @@ func (c *SQLiteConn) Close() error {
return c.lastError() return c.lastError()
} }
deleteHandles(c) deleteHandles(c)
c.dbMu.Lock()
c.db = nil c.db = nil
c.dbMu.Unlock()
runtime.SetFinalizer(c, nil) runtime.SetFinalizer(c, nil)
return nil return nil
} }
func (c *SQLiteConn) dbConnOpen() bool {
if c == nil {
return false
}
c.dbMu.Lock()
defer c.dbMu.Unlock()
return c.db != nil
}
// Prepare the query string. Return a new statement. // Prepare the query string. Return a new statement.
func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) { func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) {
return c.prepare(context.Background(), query) return c.prepare(context.Background(), query)
@ -713,7 +726,7 @@ func (s *SQLiteStmt) Close() error {
return nil return nil
} }
s.closed = true s.closed = true
if s.c == nil || s.c.db == nil { if !s.c.dbConnOpen() {
return errors.New("sqlite statement with already closed database connection") return errors.New("sqlite statement with already closed database connection")
} }
rv := C.sqlite3_finalize(s.s) rv := C.sqlite3_finalize(s.s)