diff options
author | mattn <mattn.jp@gmail.com> | 2017-06-18 12:59:56 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-18 12:59:56 +0900 |
commit | a819994f72c9c22cbe7d0849038a394d8154d4c9 (patch) | |
tree | 40a8bef15df9ef56a1445c2a42b5cb87a22d4e6d | |
parent | Merge pull request #425 from xxr3376/empty-bytes (diff) | |
parent | Sync database-close and statement-close (diff) | |
download | golite-a819994f72c9c22cbe7d0849038a394d8154d4c9.tar.gz golite-a819994f72c9c22cbe7d0849038a394d8154d4c9.tar.xz |
Merge pull request #427 from otoolep/conn_stmt_race
Address data race during close database and statement
-rw-r--r-- | sqlite3.go | 15 |
1 files changed, 14 insertions, 1 deletions
@@ -113,6 +113,7 @@ import ( "runtime" "strconv" "strings" + "sync" "time" "unsafe" @@ -157,6 +158,7 @@ type SQLiteDriver struct { // SQLiteConn implement sql.Conn. type SQLiteConn struct { + dbMu sync.Mutex db *C.sqlite3 loc *time.Location txlock string @@ -679,11 +681,22 @@ func (c *SQLiteConn) Close() error { return c.lastError() } deleteHandles(c) + c.dbMu.Lock() c.db = nil + c.dbMu.Unlock() runtime.SetFinalizer(c, 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. func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) { return c.prepare(context.Background(), query) @@ -713,7 +726,7 @@ func (s *SQLiteStmt) Close() error { return nil } 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") } rv := C.sqlite3_finalize(s.s) |