Commits

Vadim Savchuk committed 60edd8d

STORM-192 ADDITIONAL FIX Fixed crash on pressing Ctrl+Shift+W (which closes all floaters).

The crash was introduced by my previous fix of this ticket in changeset 8ceebd3612f0.
The problem was that, suprisingly, even invisible (faded) toasts were destroyed when you hit Ctrl_Shift+W,
however they were still referenced by the toast pool, so the references were invalidated.

The easiest fix would be to remove all references to the toast being destroyed, no matter is it visible or not.
However, then we'd have to search for each destroyed toast in the pool, which is slow.
Besides, removing toasts from the pool compromises the whole idea of pooling (which was introduced to speed up creation of new toasts).

Another possible fix is not to destroy any nearby chat toasts when user hits Ctrl+Shift+W.
That would save us from any crashes at a price of changing existing behaviour (the toasts will remain visible).

So I went for a third option: when closing all floaters, skip invisible ones.
Then there won't be attempts to destroy invisible (pooled) toasts, so the crash won't happen,
and we don't seem to change any existing behavior.
However I'm not 100% sure of the latter statement, so the fix requires extensive testing.

  • Participants
  • Parent commits d6f3234

Comments (0)

Files changed (2)

File indra/llui/llfloater.cpp

 
 		// Attempt to close floater.  This will cause the "do you want to save"
 		// dialogs to appear.
-		if (floaterp->canClose() && !floaterp->isDead())
+		// Skip invisible floaters if we're not quitting (STORM-192).
+		if (floaterp->canClose() && !floaterp->isDead() &&
+			(app_quitting || floaterp->getVisible()))
 		{
 			floaterp->closeFloater(app_quitting);
 		}

File indra/newview/llnearbychathandler.cpp

 
 class LLNearbyChatScreenChannel: public LLScreenChannelBase
 {
+	LOG_CLASS(LLNearbyChatScreenChannel);
 public:
 	LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mStopProcessing = false;};
 
 
 	virtual void deleteAllChildren()
 	{
+		LL_DEBUGS("NearbyChat") << "Clearing toast pool" << llendl;
 		m_toast_pool.clear();
 		m_active_toasts.clear();
 		LLScreenChannelBase::deleteAllChildren();
 	void	deactivateToast(LLToast* toast);
 	void	addToToastPool(LLToast* toast)
 	{
+		LL_DEBUGS("NearbyChat") << "Pooling toast" << llendl;
 		toast->setVisible(FALSE);
 		toast->stopTimer();
 		toast->setIsHidden(true);
 		return;
 	}
 
+	LL_DEBUGS("NearbyChat") << "Deactivating toast" << llendl;
 	m_active_toasts.erase(pos);
 }
 
 
 void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting)
 {	
+	LL_DEBUGS("NearbyChat") << "Toast destroyed (app_quitting=" << app_quitting << ")" << llendl;
+
 	if (app_quitting)
 	{
 		// Viewer is quitting.
 }
 
 void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
-{	
+{
+	LL_DEBUGS("NearbyChat") << "Toast fading" << llendl;
+
 	//fade mean we put toast to toast pool
 	if(!toast)
 		return;
 	
 	toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
 	
+	LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl;
 	m_toast_pool.push_back(toast);
 	return true;
 }
 	if(m_toast_pool.empty())
 	{
 		//"pool" is empty - create one more panel
+		LL_DEBUGS("NearbyChat") << "Empty pool" << llendl;
 		if(!createPoolToast())//created toast will go to pool. so next call will find it
 			return;
 		addNotification(notification);
 
 	//take 1st element from pool, (re)initialize it, put it in active toasts
 
+	LL_DEBUGS("NearbyChat") << "Getting toast from pool" << llendl;
 	LLToast* toast = m_toast_pool.back();
 
 	m_toast_pool.pop_back();