From 1ebd4aa913ff2c1bf23bd1985e12f09d0a415fdd Mon Sep 17 00:00:00 2001 From: StalkR Date: Tue, 31 Mar 2015 23:49:40 +0200 Subject: [PATCH] client/connection: fix deadlock on event dispatch --- client/connection.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/connection.go b/client/connection.go index c577b51..a7f3f95 100644 --- a/client/connection.go +++ b/client/connection.go @@ -207,6 +207,8 @@ func (conn *Conn) DisableStateTracking() { // Per-connection state initialisation. func (conn *Conn) initialise() { + conn.mu.Lock() + defer conn.mu.Unlock() conn.io = nil conn.sock = nil conn.die = make(chan struct{}) @@ -404,8 +406,8 @@ 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() conn.mu.Lock() - defer conn.mu.Unlock() if !conn.connected { + conn.mu.Unlock() return } logging.Info("irc.shutdown(): Disconnected from server.") @@ -415,6 +417,8 @@ func (conn *Conn) shutdown() { conn.wg.Wait() // Dispatch after closing connection but before reinit // so event handlers can still access state information. + // Release lock before dispatch or we block handlers from accessing Me() + conn.mu.Unlock() conn.dispatch(&Line{Cmd: DISCONNECTED, Time: time.Now()}) // reinit datastructures ready for next connection conn.initialise()