Skip to content

Commit fe777b1

Browse files
committed
make sure Close always removes the runtime finalizer
This commit fixes a bug in {SQLiteConn,SQLiteStmt}.Close that would lead to the runtime finalizer not being removed if there was an error closing the connection or statement. This commit also makes it safe to call SQLiteConn.Close multiple times.
1 parent ab13d63 commit fe777b1

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

sqlite3.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,17 +1782,20 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
17821782
}
17831783

17841784
// Close the connection.
1785-
func (c *SQLiteConn) Close() error {
1785+
func (c *SQLiteConn) Close() (err error) {
1786+
c.mu.Lock()
1787+
defer c.mu.Unlock()
1788+
if c.db == nil {
1789+
return nil // Already closed
1790+
}
1791+
runtime.SetFinalizer(c, nil)
17861792
rv := C.sqlite3_close_v2(c.db)
17871793
if rv != C.SQLITE_OK {
1788-
return c.lastError()
1794+
err = c.lastError()
17891795
}
17901796
deleteHandles(c)
1791-
c.mu.Lock()
17921797
c.db = nil
1793-
c.mu.Unlock()
1794-
runtime.SetFinalizer(c, nil)
1795-
return nil
1798+
return err
17961799
}
17971800

17981801
func (c *SQLiteConn) dbConnOpen() bool {
@@ -1901,16 +1904,18 @@ func (s *SQLiteStmt) Close() error {
19011904
return nil
19021905
}
19031906
s.closed = true
1904-
if !s.c.dbConnOpen() {
1907+
conn := s.c
1908+
stmt := s.s
1909+
s.c = nil
1910+
s.s = nil
1911+
runtime.SetFinalizer(s, nil)
1912+
if !conn.dbConnOpen() {
19051913
return errors.New("sqlite statement with already closed database connection")
19061914
}
1907-
rv := C.sqlite3_finalize(s.s)
1908-
s.s = nil
1915+
rv := C.sqlite3_finalize(stmt)
19091916
if rv != C.SQLITE_OK {
1910-
return s.c.lastError()
1917+
return conn.lastError()
19111918
}
1912-
s.c = nil
1913-
runtime.SetFinalizer(s, nil)
19141919
return nil
19151920
}
19161921

0 commit comments

Comments
 (0)