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" "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 {