aboutsummaryrefslogtreecommitdiff
path: root/src/database/sql/sql.go
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2023-07-07 16:49:15 -0400
committerThan McIntosh <thanm@google.com>2023-07-07 16:49:15 -0400
commit71aaa8bde1ba983894121987aaf09cb2012ab622 (patch)
tree12c26e401a50654e0d557b98b2136b18b5ee9d97 /src/database/sql/sql.go
parent3aba453b66371647dfad4e901fca578d2b564e09 (diff)
parent894d24d617bb72d6e1bed7b143f9f7a0ac16b844 (diff)
downloadgo-71aaa8bde1ba983894121987aaf09cb2012ab622.tar.gz
go-71aaa8bde1ba983894121987aaf09cb2012ab622.zip
[dev.inline] merge with master at 894d24d617dev.inline
Change-Id: I845eec08108c69228ebcba921f8a807a376d3fae
Diffstat (limited to 'src/database/sql/sql.go')
-rw-r--r--src/database/sql/sql.go17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index a77d63dc5e..836fe83e2e 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -2944,15 +2944,17 @@ func (rs *Rows) initContextClose(ctx, txctx context.Context) {
if bypassRowsAwaitDone {
return
}
- ctx, rs.cancel = context.WithCancel(ctx)
- go rs.awaitDone(ctx, txctx)
+ closectx, cancel := context.WithCancel(ctx)
+ rs.cancel = cancel
+ go rs.awaitDone(ctx, txctx, closectx)
}
-// awaitDone blocks until either ctx or txctx is canceled. The ctx is provided
-// from the query context and is canceled when the query Rows is closed.
+// awaitDone blocks until ctx, txctx, or closectx is canceled.
+// The ctx is provided from the query context.
// If the query was issued in a transaction, the transaction's context
-// is also provided in txctx to ensure Rows is closed if the Tx is closed.
-func (rs *Rows) awaitDone(ctx, txctx context.Context) {
+// is also provided in txctx, to ensure Rows is closed if the Tx is closed.
+// The closectx is closed by an explicit call to rs.Close.
+func (rs *Rows) awaitDone(ctx, txctx, closectx context.Context) {
var txctxDone <-chan struct{}
if txctx != nil {
txctxDone = txctx.Done()
@@ -2964,6 +2966,9 @@ func (rs *Rows) awaitDone(ctx, txctx context.Context) {
case <-txctxDone:
err := txctx.Err()
rs.contextDone.Store(&err)
+ case <-closectx.Done():
+ // rs.cancel was called via Close(); don't store this into contextDone
+ // to ensure Err() is unaffected.
}
rs.close(ctx.Err())
}