Fix race condition with canceled contexts
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -74,8 +75,6 @@ type Conn struct {
|
|||||||
preparedStatements map[string]*PreparedStatement
|
preparedStatements map[string]*PreparedStatement
|
||||||
channels map[string]struct{}
|
channels map[string]struct{}
|
||||||
notifications []*Notification
|
notifications []*Notification
|
||||||
alive bool
|
|
||||||
causeOfDeath error
|
|
||||||
logger Logger
|
logger Logger
|
||||||
logLevel int
|
logLevel int
|
||||||
mr msgReader
|
mr msgReader
|
||||||
@@ -85,6 +84,10 @@ type Conn struct {
|
|||||||
busy bool
|
busy bool
|
||||||
poolResetCount int
|
poolResetCount int
|
||||||
preallocatedRows []Rows
|
preallocatedRows []Rows
|
||||||
|
|
||||||
|
closingLock sync.Mutex
|
||||||
|
alive bool
|
||||||
|
causeOfDeath error
|
||||||
}
|
}
|
||||||
|
|
||||||
// PreparedStatement is a description of a prepared statement
|
// PreparedStatement is a description of a prepared statement
|
||||||
@@ -391,14 +394,14 @@ func (c *Conn) loadInetConstants() error {
|
|||||||
// Close closes a connection. It is safe to call Close on a already closed
|
// Close closes a connection. It is safe to call Close on a already closed
|
||||||
// connection.
|
// connection.
|
||||||
func (c *Conn) Close() (err error) {
|
func (c *Conn) Close() (err error) {
|
||||||
if !c.IsAlive() {
|
c.closingLock.Lock()
|
||||||
|
defer c.closingLock.Unlock()
|
||||||
|
|
||||||
|
if !c.alive {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
wbuf := newWriteBuf(c, 'X')
|
_, err = c.conn.Write([]byte{'X', 0, 0, 0, 4})
|
||||||
wbuf.closeMsg()
|
|
||||||
|
|
||||||
_, err = c.conn.Write(wbuf.buf)
|
|
||||||
|
|
||||||
c.die(errors.New("Closed"))
|
c.die(errors.New("Closed"))
|
||||||
if c.shouldLog(LogLevelInfo) {
|
if c.shouldLog(LogLevelInfo) {
|
||||||
@@ -870,7 +873,10 @@ func (c *Conn) waitForNotification(deadline time.Time) (*Notification, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) IsAlive() bool {
|
func (c *Conn) IsAlive() bool {
|
||||||
return c.alive
|
c.closingLock.Lock()
|
||||||
|
alive := c.alive
|
||||||
|
c.closingLock.Unlock()
|
||||||
|
return alive
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) CauseOfDeath() error {
|
func (c *Conn) CauseOfDeath() error {
|
||||||
|
|||||||
Reference in New Issue
Block a user