From 1a7169d75d21c6f6a44b6f769a378c6f24b23085 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 27 May 2019 05:52:40 -0400 Subject: [PATCH] fix double-destroy bug --- irc/client.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/irc/client.go b/irc/client.go index 7d0f0a0e..c31bdd28 100644 --- a/irc/client.go +++ b/irc/client.go @@ -53,6 +53,7 @@ type Client struct { certfp string channels ChannelSet ctime time.Time + destroyed bool exitedSnomaskSent bool flags modes.ModeSet hostname string @@ -962,7 +963,6 @@ func (client *Client) Quit(message string, session *Session) { func (client *Client) destroy(session *Session) { var sessionsToDestroy []*Session - // allow destroy() to execute at most once client.stateMutex.Lock() details := client.detailsNoMutex() brbState := client.brbTimer.state @@ -980,6 +980,13 @@ func (client *Client) destroy(session *Session) { sessionsToDestroy = []*Session{session} } } + + // should we destroy the whole client this time? + shouldDestroy := !client.destroyed && remainingSessions == 0 && (brbState != BrbEnabled && brbState != BrbSticky) + if shouldDestroy { + // if it's our job to destroy it, don't let anyone else try + client.destroyed = true + } client.stateMutex.Unlock() // destroy all applicable sessions: @@ -1013,8 +1020,7 @@ func (client *Client) destroy(session *Session) { } // do not destroy the client if it has either remaining sessions, or is BRB'ed - if remainingSessions != 0 || brbState == BrbEnabled || brbState == BrbSticky { - client.server.logger.Debug("quit", fmt.Sprintf("preserving client %s with %d remaining sessions\n", details.nick, remainingSessions)) + if !shouldDestroy { return }