Skip to content

Commit 83baa77

Browse files
authored
Merge pull request #1416 from mattn/fix-stmt-close-race
Fix race in SQLiteStmt.Close by holding conn lock across cache check
2 parents a40eeff + 34c9c34 commit 83baa77

1 file changed

Lines changed: 22 additions & 10 deletions

File tree

sqlite3.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -445,12 +445,12 @@ type SQLiteDriver struct {
445445

446446
// SQLiteConn implements driver.Conn.
447447
type SQLiteConn struct {
448-
mu sync.Mutex
449-
db *C.sqlite3
450-
loc *time.Location
451-
txlock string
452-
funcs []*functionInfo
453-
aggregators []*aggInfo
448+
mu sync.Mutex
449+
db *C.sqlite3
450+
loc *time.Location
451+
txlock string
452+
funcs []*functionInfo
453+
aggregators []*aggInfo
454454
// Prepared-statement cache. The slice is allocated at Open with a
455455
// fixed capacity equal to the configured cache size; cap bounds the
456456
// cache, len is the live count, and entries are ordered LRU-first
@@ -1970,6 +1970,10 @@ func (c *SQLiteConn) putCachedStmt(s *SQLiteStmt) bool {
19701970
c.mu.Lock()
19711971
defer c.mu.Unlock()
19721972

1973+
return c.putCachedStmtLocked(s)
1974+
}
1975+
1976+
func (c *SQLiteConn) putCachedStmtLocked(s *SQLiteStmt) bool {
19731977
if c.db == nil {
19741978
return false
19751979
}
@@ -2164,12 +2168,20 @@ func (s *SQLiteStmt) Close() error {
21642168
s.c = nil
21652169
return nil
21662170
}
2167-
if !conn.dbConnOpen() {
2171+
if s.cacheKey != "" {
2172+
conn.mu.Lock()
2173+
if conn.db == nil {
2174+
conn.mu.Unlock()
2175+
return errors.New("sqlite statement with already closed database connection")
2176+
}
2177+
if conn.putCachedStmtLocked(s) {
2178+
conn.mu.Unlock()
2179+
return nil
2180+
}
2181+
conn.mu.Unlock()
2182+
} else if !conn.dbConnOpen() {
21682183
return errors.New("sqlite statement with already closed database connection")
21692184
}
2170-
if s.cacheKey != "" && conn.putCachedStmt(s) {
2171-
return nil
2172-
}
21732185
s.s = nil
21742186
s.c = nil
21752187
rv := C.sqlite3_finalize(stmt)

0 commit comments

Comments
 (0)