diff options
author | Than McIntosh <thanm@google.com> | 2023-07-07 16:49:15 -0400 |
---|---|---|
committer | Than McIntosh <thanm@google.com> | 2023-07-07 16:49:15 -0400 |
commit | 71aaa8bde1ba983894121987aaf09cb2012ab622 (patch) | |
tree | 12c26e401a50654e0d557b98b2136b18b5ee9d97 /src/database/sql/sql.go | |
parent | 3aba453b66371647dfad4e901fca578d2b564e09 (diff) | |
parent | 894d24d617bb72d6e1bed7b143f9f7a0ac16b844 (diff) | |
download | go-dev.inline.tar.gz go-dev.inline.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.go | 17 |
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()) } |