Skip to content

Commit

Permalink
make sure Close always removes the runtime finalizer
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
charlievieth committed Dec 9, 2024
1 parent ab13d63 commit fe777b1
Showing 1 changed file with 17 additions and 12 deletions.
29 changes: 17 additions & 12 deletions sqlite3.go
Original file line number Diff line number Diff line change
Expand Up @@ -1782,17 +1782,20 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
}

// Close the connection.
func (c *SQLiteConn) Close() error {
func (c *SQLiteConn) Close() (err error) {
c.mu.Lock()
defer c.mu.Unlock()
if c.db == nil {
return nil // Already closed
}
runtime.SetFinalizer(c, nil)
rv := C.sqlite3_close_v2(c.db)
if rv != C.SQLITE_OK {
return c.lastError()
err = c.lastError()
}
deleteHandles(c)
c.mu.Lock()
c.db = nil
c.mu.Unlock()
runtime.SetFinalizer(c, nil)
return nil
return err
}

func (c *SQLiteConn) dbConnOpen() bool {
Expand Down Expand Up @@ -1901,16 +1904,18 @@ func (s *SQLiteStmt) Close() error {
return nil
}
s.closed = true
if !s.c.dbConnOpen() {
conn := s.c
stmt := s.s
s.c = nil
s.s = nil
runtime.SetFinalizer(s, nil)
if !conn.dbConnOpen() {
return errors.New("sqlite statement with already closed database connection")
}
rv := C.sqlite3_finalize(s.s)
s.s = nil
rv := C.sqlite3_finalize(stmt)
if rv != C.SQLITE_OK {
return s.c.lastError()
return conn.lastError()
}
s.c = nil
runtime.SetFinalizer(s, nil)
return nil
}

Expand Down

0 comments on commit fe777b1

Please sign in to comment.