forked from mirror/go-sqlite3
Fix race in ExecContext
When the context is cancelled, an interrupt should only be made if the operation is still ongoing.
This commit is contained in:
parent
c41df79ec0
commit
58004848f1
|
@ -1171,9 +1171,13 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
|
||||||
defer close(done)
|
defer close(done)
|
||||||
go func(db *C.sqlite3) {
|
go func(db *C.sqlite3) {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
|
||||||
C.sqlite3_interrupt(db)
|
|
||||||
case <-done:
|
case <-done:
|
||||||
|
case <-ctx.Done():
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
default:
|
||||||
|
C.sqlite3_interrupt(db)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}(s.c.db)
|
}(s.c.db)
|
||||||
|
|
||||||
|
|
|
@ -134,3 +134,24 @@ func TestShortTimeout(t *testing.T) {
|
||||||
t.Fatal(ctx.Err())
|
t.Fatal(ctx.Err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExecCancel(t *testing.T) {
|
||||||
|
db, err := sql.Open("sqlite3", ":memory:")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
if _, err = db.Exec("create table foo (id integer primary key)"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for n := 0; n < 100; n++ {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
_, err = db.ExecContext(ctx, "insert into foo (id) values (?)", n)
|
||||||
|
cancel()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue