Ensure Close always removes runtime finalizer to prevent memory leak

Fixes #1319
This commit is contained in:
Yasuhiro Matsumoto
2026-03-17 01:59:20 +09:00
committed by mattn
parent d71eda82d4
commit 0f12d4e815

View File

@@ -1783,15 +1783,18 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// Close the connection. // Close the connection.
func (c *SQLiteConn) Close() error { func (c *SQLiteConn) Close() error {
c.mu.Lock()
defer c.mu.Unlock()
if c.db == nil {
return nil
}
runtime.SetFinalizer(c, nil)
rv := C.sqlite3_close_v2(c.db) rv := C.sqlite3_close_v2(c.db)
if rv != C.SQLITE_OK { if rv != C.SQLITE_OK {
return c.lastError() return lastError(c.db)
} }
deleteHandles(c) deleteHandles(c)
c.mu.Lock()
c.db = nil c.db = nil
c.mu.Unlock()
runtime.SetFinalizer(c, nil)
return nil return nil
} }
@@ -1932,16 +1935,18 @@ func (s *SQLiteStmt) Close() error {
return nil return nil
} }
s.closed = true s.closed = true
if !s.c.dbConnOpen() { runtime.SetFinalizer(s, nil)
conn := s.c
stmt := s.s
s.s = nil
s.c = nil
if !conn.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(stmt)
s.s = nil
if rv != C.SQLITE_OK { if rv != C.SQLITE_OK {
return s.c.lastError() return conn.lastError()
} }
s.c = nil
runtime.SetFinalizer(s, nil)
return nil return nil
} }