aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/lib/pq/conn_go18.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/lib/pq/conn_go18.go')
-rw-r--r--vendor/github.com/lib/pq/conn_go18.go22
1 files changed, 19 insertions, 3 deletions
diff --git a/vendor/github.com/lib/pq/conn_go18.go b/vendor/github.com/lib/pq/conn_go18.go
index 09e2ea4648..8cab67c9d2 100644
--- a/vendor/github.com/lib/pq/conn_go18.go
+++ b/vendor/github.com/lib/pq/conn_go18.go
@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "sync/atomic"
"time"
)
@@ -89,10 +90,21 @@ func (cn *conn) Ping(ctx context.Context) error {
func (cn *conn) watchCancel(ctx context.Context) func() {
if done := ctx.Done(); done != nil {
- finished := make(chan struct{})
+ finished := make(chan struct{}, 1)
go func() {
select {
case <-done:
+ select {
+ case finished <- struct{}{}:
+ default:
+ // We raced with the finish func, let the next query handle this with the
+ // context.
+ return
+ }
+
+ // Set the connection state to bad so it does not get reused.
+ cn.setBad()
+
// At this point the function level context is canceled,
// so it must not be used for the additional network
// request to cancel the query.
@@ -101,13 +113,14 @@ func (cn *conn) watchCancel(ctx context.Context) func() {
defer cancel()
_ = cn.cancel(ctxCancel)
- finished <- struct{}{}
case <-finished:
}
}()
return func() {
select {
case <-finished:
+ cn.setBad()
+ cn.Close()
case finished <- struct{}{}:
}
}
@@ -123,8 +136,11 @@ func (cn *conn) cancel(ctx context.Context) error {
defer c.Close()
{
+ bad := &atomic.Value{}
+ bad.Store(false)
can := conn{
- c: c,
+ c: c,
+ bad: bad,
}
err = can.ssl(cn.opts)
if err != nil {