From cda29adca1a4882d6201f7e232a26d561a1d33fd Mon Sep 17 00:00:00 2001
From: Mike Antipov <mantipov@productengine.com>
Date: Fri, 16 Apr 2010 15:14:07 +0300
Subject: Fixed major bug EXT-6869 (Viewer crashes when switching between group
 voice sessions)

The reason: LLCallDialogManager did not disconnect from "voice channel state changed" signal on channel in previous session.
    Thus when old channel changes state from STATE_HUNG_UP to STATE_CALL_STARTED there is invalid pointer to session in connected LLCallDialogManager::onVoiceChannelStateChanged callback before current voice channel is changed and pointer to session becames valid.

Fix: add storing of connection to signal in voice channel from previous session and disconnect it before connecting to channel in current session.

Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/244/

--HG--
branch : product-engine
---
 indra/newview/llimview.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 7a4febec20..4780e985ca 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1437,7 +1437,13 @@ void LLCallDialogManager::onVoiceChannelChanged(const LLUUID &session_id)
 	}
 
 	sSession = session;
-	sSession->mVoiceChannel->setStateChangedCallback(boost::bind(LLCallDialogManager::onVoiceChannelStateChanged, _1, _2, _3, _4));
+
+	static boost::signals2::connection prev_channel_state_changed_connection;
+	// disconnect previously connected callback to avoid have invalid sSession in onVoiceChannelStateChanged()
+	prev_channel_state_changed_connection.disconnect();
+	prev_channel_state_changed_connection =
+		sSession->mVoiceChannel->setStateChangedCallback(boost::bind(LLCallDialogManager::onVoiceChannelStateChanged, _1, _2, _3, _4));
+
 	if(sCurrentSessionlName != session->mName)
 	{
 		sPreviousSessionlName = sCurrentSessionlName;
-- 
cgit v1.2.3