2
0

Fix race condition with canceled contexts

This commit is contained in:
Jack Christensen
2017-02-04 18:44:55 -06:00
parent 94eea5128e
commit 37b86083e4
+14 -8
View File
@@ -18,6 +18,7 @@ import (
"regexp"
"strconv"
"strings"
"sync"
"time"
)
@@ -74,8 +75,6 @@ type Conn struct {
preparedStatements map[string]*PreparedStatement
channels map[string]struct{}
notifications []*Notification
alive bool
causeOfDeath error
logger Logger
logLevel int
mr msgReader
@@ -85,6 +84,10 @@ type Conn struct {
busy bool
poolResetCount int
preallocatedRows []Rows
closingLock sync.Mutex
alive bool
causeOfDeath error
}
// 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
// connection.
func (c *Conn) Close() (err error) {
if !c.IsAlive() {
c.closingLock.Lock()
defer c.closingLock.Unlock()
if !c.alive {
return nil
}
wbuf := newWriteBuf(c, 'X')
wbuf.closeMsg()
_, err = c.conn.Write(wbuf.buf)
_, err = c.conn.Write([]byte{'X', 0, 0, 0, 4})
c.die(errors.New("Closed"))
if c.shouldLog(LogLevelInfo) {
@@ -870,7 +873,10 @@ func (c *Conn) waitForNotification(deadline time.Time) (*Notification, error) {
}
func (c *Conn) IsAlive() bool {
return c.alive
c.closingLock.Lock()
alive := c.alive
c.closingLock.Unlock()
return alive
}
func (c *Conn) CauseOfDeath() error {