fix race and reinit conn.Me on disconnect

* due to the blocking nature of channel reads, by the time the runLoop()
  for loop exits in that goroutine, we might well be half-way through
  reconnecting to the server -- a bad time to run conn.initialise().
  move the call to initialise() into shutdown() to ensure it happens
  in a timely manner.

* On a related note, conn.Me was retaining old channel objects in it's
  Channels map. All other references to nicks and channels are erased
  in conn.initialise(), but as we keep a seperate reference to our Nick
  object in conn.Me, we need to reinit that at the same time.
This commit is contained in:
Alex Bramley 2009-12-19 19:00:27 +00:00
parent 03e5b3a84e
commit 17e5216144
1 changed files with 9 additions and 4 deletions

View File

@ -69,6 +69,12 @@ func (conn *Conn) initialise() {
conn.Err = make(chan os.Error, 4) conn.Err = make(chan os.Error, 4)
conn.io = nil conn.io = nil
conn.sock = nil conn.sock = nil
// if this is being called because we are reconnecting, conn.Me
// will still have all the old channels referenced -- nuke them!
if conn.Me != nil {
conn.Me = conn.NewNick(conn.Me.Nick, conn.Me.Ident, conn.Me.Name, "")
}
} }
// Connect the IRC connection object to "host[:port]" which should be either // Connect the IRC connection object to "host[:port]" which should be either
@ -200,10 +206,6 @@ func (conn *Conn) runLoop() {
for line := range conn.in { for line := range conn.in {
conn.dispatchEvent(line) conn.dispatchEvent(line)
} }
// if we fall off the end here due to shutdown,
// reinit everything once the runloop is done
// so that Connect() can be called again.
conn.initialise()
} }
func (conn *Conn) shutdown() { func (conn *Conn) shutdown() {
@ -212,6 +214,9 @@ func (conn *Conn) shutdown() {
close(conn.Err) close(conn.Err)
conn.connected = false conn.connected = false
conn.sock.Close() conn.sock.Close()
// 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 // Dumps a load of information about the current state of the connection to a