From cf98cdf69f481dd473363d4a80a80f27e96f87e8 Mon Sep 17 00:00:00 2001
From: Richard Nelson <richard@lindenlab.com>
Date: Fri, 14 Oct 2011 16:43:43 -0700
Subject: [PATCH] fix for crash on exit

---
 indra/newview/llchannelmanager.cpp | 23 ++++++++++++++++-------
 indra/newview/llchannelmanager.h   |  6 +++---
 indra/newview/llscreenchannel.h    |  2 ++
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 59842aeb6c8..ca635eaa8f7 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -58,7 +58,10 @@ LLChannelManager::~LLChannelManager()
 {
 	for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it !=  mChannelList.end(); ++it)
 	{
-		delete (*it).channel;
+		LLScreenChannelBase* channel = it->channel.get();
+		if (!channel) continue;
+
+		delete channel;
 	}
 
 	mChannelList.clear();
@@ -84,16 +87,19 @@ void LLChannelManager::onLoginCompleted()
 	// calc a number of all offline notifications
 	for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it !=  mChannelList.end(); ++it)
 	{
+		LLScreenChannelBase* channel = it->channel.get();
+		if (!channel) continue;
+
 		// don't calc notifications for Nearby Chat
-		if((*it).channel->getChannelID() == LLUUID(gSavedSettings.getString("NearByChatChannelUUID")))
+		if(channel->getChannelID() == LLUUID(gSavedSettings.getString("NearByChatChannelUUID")))
 		{
 			continue;
 		}
 
 		// don't calc notifications for channels that always show their notifications
-		if(!(*it).channel->getDisplayToastsAlways())
+		if(!channel->getDisplayToastsAlways())
 		{
-			away_notifications +=(*it).channel->getNumberOfHiddenToasts();
+			away_notifications +=channel->getNumberOfHiddenToasts();
 		}
 	}
 
@@ -157,7 +163,7 @@ LLScreenChannelBase*	LLChannelManager::addChannel(LLScreenChannelBase* channel)
 
 	ChannelElem new_elem;
 	new_elem.id = channel->getChannelID();
-	new_elem.channel = channel;
+	new_elem.channel = channel->getHandle();
 
 	mChannelList.push_back(new_elem); 
 
@@ -189,7 +195,7 @@ LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID& id)
 	std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id); 
 	if(it != mChannelList.end())
 	{
-		return (*it).channel;
+		return (*it).channel.get();
 	}
 
 	return NULL;
@@ -211,7 +217,10 @@ void LLChannelManager::muteAllChannels(bool mute)
 	for (std::vector<ChannelElem>::iterator it = mChannelList.begin();
 			it != mChannelList.end(); it++)
 	{
-		it->channel->setShowToasts(!mute);
+		if (it->channel.get())
+		{
+			it->channel.get()->setShowToasts(!mute);
+		}
 	}
 }
 
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index 671e545465e..a5de8a53271 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -48,10 +48,10 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 
 	struct ChannelElem
 	{
-		LLUUID				id;
-		LLScreenChannelBase*	channel;
+		LLUUID							id;
+		LLHandle<LLScreenChannelBase>	channel;
 
-		ChannelElem() : id(LLUUID("")), channel(NULL) { }
+		ChannelElem() { }
 
 		ChannelElem(const ChannelElem &elem)
 		{
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 4d8e3e9e931..f4f52eea197 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -113,6 +113,7 @@ class LLScreenChannelBase : public LLUICtrl
 	
 	// get ID of a channel
 	LLUUID	getChannelID() { return mID; }
+	LLHandle<LLScreenChannelBase> getHandle() { mRootHandle.bind(this); return mRootHandle; }
 
 protected:
 	void	updateBottom();
@@ -124,6 +125,7 @@ class LLScreenChannelBase : public LLUICtrl
 	bool		mDisplayToastsAlways;
 	// controls whether a channel shows toasts or not
 	bool		mShowToasts;
+	LLRootHandle<LLScreenChannelBase> mRootHandle;
 	// 
 	EToastAlignment		mToastAlignment;
 	EChannelAlignment	mChannelAlignment;
-- 
GitLab