summaryrefslogtreecommitdiffstats
path: root/vendor/modernc.org/sqlite/sqlite.go
diff options
context:
space:
mode:
authorWim <wim@42.be>2022-03-19 22:04:13 +0100
committerWim <wim@42.be>2022-03-20 14:57:48 +0100
commit2623a412c42a81104b97ae8c81a5f66760fee4b6 (patch)
tree502c6d4473baac3792d14fda51dbb56179f19424 /vendor/modernc.org/sqlite/sqlite.go
parentd64eed49bc6f2e8a01f922727795eea158cbc56d (diff)
downloadmatterbridge-msglm-2623a412c42a81104b97ae8c81a5f66760fee4b6.tar.gz
matterbridge-msglm-2623a412c42a81104b97ae8c81a5f66760fee4b6.tar.bz2
matterbridge-msglm-2623a412c42a81104b97ae8c81a5f66760fee4b6.zip
Update vendor (whatsapp)
Diffstat (limited to 'vendor/modernc.org/sqlite/sqlite.go')
-rw-r--r--vendor/modernc.org/sqlite/sqlite.go81
1 files changed, 40 insertions, 41 deletions
diff --git a/vendor/modernc.org/sqlite/sqlite.go b/vendor/modernc.org/sqlite/sqlite.go
index a484a2d0..f8c696f6 100644
--- a/vendor/modernc.org/sqlite/sqlite.go
+++ b/vendor/modernc.org/sqlite/sqlite.go
@@ -491,20 +491,7 @@ func (s *stmt) exec(ctx context.Context, args []driver.NamedValue) (r driver.Res
var pstmt uintptr
var done int32
if ctx != nil && ctx.Done() != nil {
- donech := make(chan struct{})
-
- go func() {
- select {
- case <-ctx.Done():
- atomic.AddInt32(&done, 1)
- s.c.interrupt(s.c.db)
- case <-donech:
- }
- }()
-
- defer func() {
- close(donech)
- }()
+ defer interruptOnDone(ctx, s.c, &done)()
}
for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0 && atomic.LoadInt32(&done) == 0; {
@@ -588,20 +575,7 @@ func (s *stmt) query(ctx context.Context, args []driver.NamedValue) (r driver.Ro
var pstmt uintptr
var done int32
if ctx != nil && ctx.Done() != nil {
- donech := make(chan struct{})
-
- go func() {
- select {
- case <-ctx.Done():
- atomic.AddInt32(&done, 1)
- s.c.interrupt(s.c.db)
- case <-donech:
- }
- }()
-
- defer func() {
- close(donech)
- }()
+ defer interruptOnDone(ctx, s.c, &done)()
}
var allocs []uintptr
@@ -718,19 +692,7 @@ func (t *tx) exec(ctx context.Context, sql string) (err error) {
//TODO use t.conn.ExecContext() instead
if ctx != nil && ctx.Done() != nil {
- donech := make(chan struct{})
-
- go func() {
- select {
- case <-ctx.Done():
- t.c.interrupt(t.c.db)
- case <-donech:
- }
- }()
-
- defer func() {
- close(donech)
- }()
+ defer interruptOnDone(ctx, t.c, nil)()
}
if rc := sqlite3.Xsqlite3_exec(t.c.tls, t.c.db, psql, 0, 0, 0); rc != sqlite3.SQLITE_OK {
@@ -740,6 +702,43 @@ func (t *tx) exec(ctx context.Context, sql string) (err error) {
return nil
}
+// interruptOnDone sets up a goroutine to interrupt the provided db when the
+// context is canceled, and returns a function the caller must defer so it
+// doesn't interrupt after the caller finishes.
+func interruptOnDone(
+ ctx context.Context,
+ c *conn,
+ done *int32,
+) func() {
+ if done == nil {
+ var d int32
+ done = &d
+ }
+
+ donech := make(chan struct{})
+
+ go func() {
+ select {
+ case <-ctx.Done():
+ // don't call interrupt if we were already done: it indicates that this
+ // call to exec is no longer running and we would be interrupting
+ // nothing, or even possibly an unrelated later call to exec.
+ if atomic.AddInt32(done, 1) == 1 {
+ c.interrupt(c.db)
+ }
+ case <-donech:
+ }
+ }()
+
+ // the caller is expected to defer this function
+ return func() {
+ // set the done flag so that a context cancellation right after the caller
+ // returns doesn't trigger a call to interrupt for some other statement.
+ atomic.AddInt32(done, 1)
+ close(donech)
+ }
+}
+
type conn struct {
db uintptr // *sqlite3.Xsqlite3
tls *libc.TLS