diff options
author | Wim <wim@42.be> | 2022-03-19 22:04:13 +0100 |
---|---|---|
committer | Wim <wim@42.be> | 2022-03-20 14:57:48 +0100 |
commit | 2623a412c42a81104b97ae8c81a5f66760fee4b6 (patch) | |
tree | 502c6d4473baac3792d14fda51dbb56179f19424 /vendor/modernc.org/sqlite/sqlite.go | |
parent | d64eed49bc6f2e8a01f922727795eea158cbc56d (diff) | |
download | matterbridge-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.go | 81 |
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 |