From 415ccc76078236bd8804e2c92e1ebc68d52f528a Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Wed, 12 Feb 2014 21:04:50 -0800 Subject: [PATCH] maybe fix networking hangs --- irc/channel.go | 23 ++++++++++++----------- irc/client.go | 22 ++++++++++------------ irc/types.go | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index d778fb05..29a0d1a7 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -7,6 +7,7 @@ import ( type Channel struct { banList []UserMask commands chan<- ChannelCommand + destroyed bool key string members ClientSet name string @@ -46,23 +47,23 @@ func NewChannel(s *Server, name string) *Channel { return channel } -func (channel *Channel) Destroy() error { - if channel.replies == nil { - return ErrAlreadyDestroyed +func (channel *Channel) Destroy() { + if channel.destroyed { + return } + close(channel.replies) - channel.replies = nil - return nil + close(channel.commands) + + channel.server.channels.Remove(channel) + + channel.destroyed = true } -func (channel *Channel) Reply(replies ...Reply) error { - if channel.replies == nil { - return ErrAlreadyDestroyed - } +func (channel *Channel) Reply(replies ...Reply) { for _, reply := range replies { channel.replies <- reply } - return nil } func (channel *Channel) receiveCommands(commands <-chan ChannelCommand) { @@ -183,7 +184,7 @@ func (m *PartCommand) HandleChannel(channel *Channel) { // TODO persistent channels if channel.IsEmpty() { - channel.server.channels.Remove(channel) + channel.Destroy() } } diff --git a/irc/client.go b/irc/client.go index e43c2df0..a0c26f90 100644 --- a/irc/client.go +++ b/irc/client.go @@ -15,6 +15,7 @@ type Client struct { awayMessage string channels ChannelSet conn net.Conn + destroyed bool hostname string idleTimer *time.Timer invisible bool @@ -106,6 +107,7 @@ func (c *Client) readConn() { m.SetClient(c) c.server.commands <- m } + c.Destroy() } func (client *Client) maybeLogWriteError(err error) bool { @@ -138,18 +140,18 @@ func (client *Client) writeConn(replies <-chan Reply) { } } } + client.Destroy() } -func (client *Client) Destroy() error { - if client.replies == nil { - return ErrAlreadyDestroyed +func (client *Client) Destroy() { + if client.destroyed { + return } - close(client.replies) - client.replies = nil - client.conn.Close() + close(client.replies) + if client.idleTimer != nil { client.idleTimer.Stop() } @@ -161,17 +163,13 @@ func (client *Client) Destroy() error { // clear channel list client.channels = make(ChannelSet) - return nil + client.destroyed = true } -func (client *Client) Reply(replies ...Reply) error { - if client.replies == nil { - return ErrAlreadyDestroyed - } +func (client *Client) Reply(replies ...Reply) { for _, reply := range replies { client.replies <- reply } - return nil } func (client *Client) HasNick() bool { diff --git a/irc/types.go b/irc/types.go index 585f99b2..d62f4826 100644 --- a/irc/types.go +++ b/irc/types.go @@ -108,7 +108,7 @@ type Identifier interface { } type Replier interface { - Reply(...Reply) error + Reply(...Reply) } type Reply interface {