From 12bcc94eebb604bc120325c9881a96e65d457d6c Mon Sep 17 00:00:00 2001 From: Alex Bramley Date: Mon, 18 Feb 2013 01:36:52 +0000 Subject: [PATCH] Add mutex for connect/disconnect locking. --- client/connection.go | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/client/connection.go b/client/connection.go index e9a702a..222fb07 100644 --- a/client/connection.go +++ b/client/connection.go @@ -8,11 +8,14 @@ import ( "github.com/fluffle/golog/logging" "net" "strings" + "sync" "time" ) // An IRC connection is represented by this struct. type Conn struct { + // For preventing races on (dis)connect. + mu sync.Mutex // Contains parameters that people can tweak to change client behaviour. cfg *Config @@ -164,6 +167,9 @@ func (conn *Conn) ConnectTo(host string, pass ...string) error { } func (conn *Conn) Connect() error { + conn.mu.Lock() + defer conn.mu.Unlock() + if conn.cfg.Server == "" { return fmt.Errorf("irc.Connect(): cfg.Server must be non-empty") } @@ -326,18 +332,21 @@ func (conn *Conn) rateLimit(chars int) time.Duration { func (conn *Conn) shutdown() { // Guard against double-call of shutdown() if we get an error in send() // as calling sock.Close() will cause recv() to receive EOF in readstring() - if conn.Connected { - logging.Info("irc.shutdown(): Disconnected from server.") - conn.dispatch(&Line{Cmd: "disconnected"}) - conn.Connected = false - conn.sock.Close() - conn.cSend <- true - conn.cLoop <- true - conn.cPing <- true - // reinit datastructures ready for next connection - // do this here rather than after runLoop()'s for due to race - conn.initialise() + conn.mu.Lock() + defer conn.mu.Unlock() + if !conn.connected { + return } + logging.Info("irc.shutdown(): Disconnected from server.") + conn.dispatch(&Line{Cmd: DISCONNECTED}) + conn.connected = false + conn.sock.Close() + conn.cSend <- true + conn.cLoop <- true + conn.cPing <- true + // reinit datastructures ready for next connection + // do this here rather than after runLoop()'s for due to race + conn.initialise() } // Dumps a load of information about the current state of the connection to a