From 391ac367d6922f30bf3a186bc15e1fc38366eecf Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 19 Nov 2013 17:40:44 -0800
Subject: [PATCH] SH-4634 FIX Interesting: Viewer crashes when receiving
 teleport offer renamed fast timers to have unique names, changes instance
 tracker to never allow duplicates

---
 indra/llcommon/llinstancetracker.h           | 46 +++++++++++++-------
 indra/llcommon/lltrace.h                     |  4 +-
 indra/llcommon/lltraceaccumulators.h         | 10 ++---
 indra/llui/llstatbar.cpp                     |  8 ++--
 indra/newview/llappviewer.cpp                |  1 +
 indra/newview/llconversationview.cpp         |  7 +--
 indra/newview/llfloaterimnearbychat.cpp      |  3 +-
 indra/newview/llfloaterimsessiontab.cpp      | 36 +++++++--------
 indra/newview/llfolderviewmodelinventory.cpp |  2 +-
 indra/newview/llhudmanager.cpp               |  4 +-
 indra/newview/llmaterialmgr.cpp              |  2 +-
 indra/newview/lltoastnotifypanel.cpp         |  2 +-
 indra/newview/lltoastnotifypanel.h           |  2 +-
 indra/newview/llviewerdisplay.cpp            |  4 +-
 indra/newview/llviewermedia.cpp              |  4 +-
 indra/newview/llviewertexturelist.cpp        |  4 +-
 indra/newview/pipeline.cpp                   |  2 +-
 17 files changed, 79 insertions(+), 62 deletions(-)

diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 3107415ccf4..cfe690b9ec4 100755
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -64,8 +64,8 @@ LL_COMMON_API void assert_main_thread();
 
 enum EInstanceTrackerAllowKeyCollisions
 {
-	LLInstanceTrackerAllowKeyCollisions,
-	LLInstanceTrackerDisallowKeyCollisions
+	LLInstanceTrackerErrorOnCollision,
+	LLInstanceTrackerReplaceOnCollision
 };
 
 /// This mix-in class adds support for tracking all instances of the specified class parameter T
@@ -73,7 +73,7 @@ enum EInstanceTrackerAllowKeyCollisions
 /// If KEY is not provided, then instances are stored in a simple set
 /// @NOTE: see explicit specialization below for default KEY==void case
 /// @NOTE: this class is not thread-safe unless used as read-only
-template<typename T, typename KEY = void, EInstanceTrackerAllowKeyCollisions ALLOW_KEY_COLLISIONS = LLInstanceTrackerDisallowKeyCollisions>
+template<typename T, typename KEY = void, EInstanceTrackerAllowKeyCollisions KEY_COLLISION_BEHAVIOR = LLInstanceTrackerErrorOnCollision>
 class LLInstanceTracker : public LLInstanceTrackerBase
 {
 	typedef LLInstanceTracker<T, KEY> self_t;
@@ -192,7 +192,7 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 	}
 
 protected:
-	LLInstanceTracker(KEY key) 
+	LLInstanceTracker(const KEY& key) 
 	{ 
 		// make sure static data outlives all instances
 		getStatic();
@@ -211,28 +211,44 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 	LLInstanceTracker( const LLInstanceTracker& );
 	const LLInstanceTracker& operator=( const LLInstanceTracker& );
 
-	void add_(KEY key) 
+	void add_(const KEY& key) 
 	{ 
 		mInstanceKey = key; 
 		InstanceMap& map = getMap_();
 		typename InstanceMap::iterator insertion_point_it = map.lower_bound(key);
-		if (ALLOW_KEY_COLLISIONS == LLInstanceTrackerDisallowKeyCollisions
-			&& insertion_point_it != map.end() 
+		if (insertion_point_it != map.end() 
 			&& insertion_point_it->first == key)
-		{
-			LL_ERRS() << "Key " << key << " already exists in instance map for " << typeid(T).name() << LL_ENDL;
+		{ // found existing entry with that key
+			switch(KEY_COLLISION_BEHAVIOR)
+			{
+				case LLInstanceTrackerErrorOnCollision:
+				{
+					// use assert here instead of LL_ERRS(), otherwise the error will be ignored since this call is made during global object initialization
+					llassert_always_msg(false, "ERROR: Instance with this same key already exists!");
+					break;
+				}
+				case LLInstanceTrackerReplaceOnCollision:
+				{
+					// replace pointer, but leave key (should have compared equal anyway)
+					insertion_point_it->second = static_cast<T*>(this);
+					break;
+				}
+				default:
+					break;
+			}
 		}
 		else
-		{
+		{ // new key
 			map.insert(insertion_point_it, std::make_pair(key, static_cast<T*>(this)));
 		}
 	}
 	void remove_()
 	{
-		typename InstanceMap::iterator iter = getMap_().find(mInstanceKey);
-		if (iter != getMap_().end())
+		InstanceMap& map = getMap_();
+		typename InstanceMap::iterator iter = map.find(mInstanceKey);
+		if (iter != map.end())
 		{
-			getMap_().erase(iter);
+			map.erase(iter);
 		}
 	}
 
@@ -242,8 +258,8 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 
 /// explicit specialization for default case where KEY is void
 /// use a simple std::set<T*>
-template<typename T, EInstanceTrackerAllowKeyCollisions ALLOW_KEY_COLLISIONS>
-class LLInstanceTracker<T, void, ALLOW_KEY_COLLISIONS> : public LLInstanceTrackerBase
+template<typename T, EInstanceTrackerAllowKeyCollisions KEY_COLLISION_BEHAVIOR>
+class LLInstanceTracker<T, void, KEY_COLLISION_BEHAVIOR> : public LLInstanceTrackerBase
 {
 	typedef LLInstanceTracker<T, void> self_t;
 	typedef typename std::set<T*> InstanceSet;
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 8b67dd8f445..7e811efe71b 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -69,10 +69,10 @@ class StatBase
 template<typename ACCUMULATOR>
 class StatType 
 :	public StatBase,
-	public LLInstanceTracker<StatType<ACCUMULATOR>, std::string, LLInstanceTrackerAllowKeyCollisions>
+	public LLInstanceTracker<StatType<ACCUMULATOR>, std::string>
 {
 public:
-	typedef LLInstanceTracker<StatType<ACCUMULATOR>, std::string, LLInstanceTrackerAllowKeyCollisions> instance_tracker_t;
+	typedef LLInstanceTracker<StatType<ACCUMULATOR>, std::string> instance_tracker_t;
 	StatType(const char* name, const char* description)
 	:	instance_tracker_t(name),
 		StatBase(name, description),
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index dfa037d7c09..42fad8a7937 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -471,13 +471,13 @@ namespace LLTrace
 		//
 		// members
 		//
-		U64					mTotalTimeCounter,
-							mSelfTimeCounter;
-		S32					mCalls;
+		U64							mTotalTimeCounter,
+									mSelfTimeCounter;
+		S32							mCalls;
 		class BlockTimerStatHandle*	mParent;		// last acknowledged parent of this time block
 		class BlockTimerStatHandle*	mLastCaller;	// used to bootstrap tree construction
-		U16					mActiveCount;	// number of timers with this ID active on stack
-		bool				mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame
+		U16							mActiveCount;	// number of timers with this ID active on stack
+		bool						mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame
 
 	};
 
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index bfdc6571c2b..1bd2bc06f4b 100755
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -553,10 +553,10 @@ void LLStatBar::draw()
 void LLStatBar::setStat(const std::string& stat_name)
 {
 	using namespace LLTrace;
-	const StatType<CountAccumulator>*		count_stat;
-	const StatType<EventAccumulator>*		event_stat;
-	const StatType<SampleAccumulator>*		sample_stat;
-	const StatType<MemAccumulator>*	mem_stat;
+	const StatType<CountAccumulator>*	count_stat;
+	const StatType<EventAccumulator>*	event_stat;
+	const StatType<SampleAccumulator>*	sample_stat;
+	const StatType<MemAccumulator>*		mem_stat;
 
 	if ((count_stat = StatType<CountAccumulator>::getInstance(stat_name)))
 	{
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 060f19b84fb..9a31b6b51f7 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1262,6 +1262,7 @@ static LLTrace::BlockTimerStatHandle FTM_SERVICE_CALLBACK("Callback");
 static LLTrace::BlockTimerStatHandle FTM_AGENT_AUTOPILOT("Autopilot");
 static LLTrace::BlockTimerStatHandle FTM_AGENT_UPDATE("Update");
 
+// externally visible timers
 LLTrace::BlockTimerStatHandle FTM_FRAME("Frame");
 
 bool LLAppViewer::mainLoop()
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 82d3fe74c00..7c223d996bd 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -127,10 +127,11 @@ void LLConversationViewSession::setHighlightState(bool hihglight_state)
 
 void LLConversationViewSession::startFlashing()
 {
-	LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-
 	// Need to start flashing only when "Conversations" is opened or brought on top
-	if (isInVisibleChain() && !im_box->isMinimized() && mFlashStateOn && !mFlashStarted)
+	if (isInVisibleChain()
+		&& mFlashStateOn
+		&& !mFlashStarted
+		&& ! LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->isMinimized() )
 	{
 		mFlashStarted = true;
 		mFlashTimer->startFlashing();
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index b5d179b6de5..7a989806a1f 100755
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -89,7 +89,7 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
 
 
 LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd)
-:	LLFloaterIMSessionTab(llsd),
+:	LLFloaterIMSessionTab(LLSD(LLUUID::null)),
 	//mOutputMonitor(NULL),
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
@@ -97,7 +97,6 @@ LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd)
     mIsP2PChat = false;
 	mIsNearbyChat = true;
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
-	mSessionID = LLUUID();
 }
 
 //static
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 0ccfdb9a7be..572365fd07d 100755
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -47,24 +47,24 @@
 const F32 REFRESH_INTERVAL = 1.0f;
 
 LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
-  : LLTransientDockableFloater(NULL, true, session_id)
-  ,  mIsP2PChat(false)
-  ,  mExpandCollapseBtn(NULL)
-  ,  mTearOffBtn(NULL)
-  ,  mCloseBtn(NULL)
-  ,  mSessionID(session_id.asUUID())
-  , mConversationsRoot(NULL)
-  , mScroller(NULL)
-  , mChatHistory(NULL)
-  , mInputEditor(NULL)
-  , mInputEditorPad(0)
-  , mRefreshTimer(new LLTimer())
-  , mIsHostAttached(false)
-  , mHasVisibleBeenInitialized(false)
-  , mIsParticipantListExpanded(true)
-  , mChatLayoutPanel(NULL)
-  , mInputPanels(NULL)
-  , mChatLayoutPanelHeight(0)
+:	LLTransientDockableFloater(NULL, true, session_id),
+	mIsP2PChat(false),
+	mExpandCollapseBtn(NULL),
+	mTearOffBtn(NULL),
+	mCloseBtn(NULL),
+	mSessionID(session_id.asUUID()),
+	mConversationsRoot(NULL),
+	mScroller(NULL),
+	mChatHistory(NULL),
+	mInputEditor(NULL),
+	mInputEditorPad(0),
+	mRefreshTimer(new LLTimer()),
+	mIsHostAttached(false),
+	mHasVisibleBeenInitialized(false),
+	mIsParticipantListExpanded(true),
+	mChatLayoutPanel(NULL),
+	mInputPanels(NULL),
+	mChatLayoutPanelHeight(0)
 {
     setAutoFocus(FALSE);
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 0dc667f9f52..f128910ca77 100755
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -34,7 +34,7 @@
 //
 // class LLFolderViewModelInventory
 //
-static LLTrace::BlockTimerStatHandle FTM_INVENTORY_SORT("Sort");
+static LLTrace::BlockTimerStatHandle FTM_INVENTORY_SORT("Inventory Sort");
 
 bool LLFolderViewModelInventory::startDrag(std::vector<LLFolderViewModelItem*>& items)
 {
diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp
index 6b6d7d7e7fd..1f9b0f47b14 100755
--- a/indra/newview/llhudmanager.cpp
+++ b/indra/newview/llhudmanager.cpp
@@ -54,11 +54,11 @@ LLHUDManager::~LLHUDManager()
 {
 }
 
-static LLTrace::BlockTimerStatHandle FTM_HUD_EFFECTS("Hud Effects");
+static LLTrace::BlockTimerStatHandle FTM_UPDATE_HUD_EFFECTS("Update Hud Effects");
 
 void LLHUDManager::updateEffects()
 {
-	LL_RECORD_BLOCK_TIME(FTM_HUD_EFFECTS);
+	LL_RECORD_BLOCK_TIME(FTM_UPDATE_HUD_EFFECTS);
 	S32 i;
 	for (i = 0; i < mHUDEffects.size(); i++)
 	{
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index 973220007af..df6a42db4d8 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -527,7 +527,7 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
 	}
 }
 
-static LLTrace::BlockTimerStatHandle FTM_MATERIALS_IDLE("Materials");
+static LLTrace::BlockTimerStatHandle FTM_MATERIALS_IDLE("Idle Materials");
 
 void LLMaterialMgr::onIdle(void*)
 {
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index e6746bce82e..a4cf683114f 100755
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -57,7 +57,7 @@ LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal
 
 LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) 
 :	LLToastPanel(notification),
-	LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerAllowKeyCollisions>(notification->getID())
+	LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>(notification->getID())
 {
 	init(rect, show_images);
 }
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index 561befe0f6f..e4a75acfda0 100755
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -47,7 +47,7 @@ class LLNotificationForm;
  * @deprecated this class will be removed after all toast panel types are
  *  implemented in separate classes.
  */
-class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerAllowKeyCollisions>
+class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
 {
 public:
 	/**
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index ae163729630..981e4c40aa9 100755
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -231,7 +231,7 @@ void display_stats()
 static LLTrace::BlockTimerStatHandle FTM_PICK("Picking");
 static LLTrace::BlockTimerStatHandle FTM_RENDER("Render");
 static LLTrace::BlockTimerStatHandle FTM_UPDATE_SKY("Update Sky");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_TEXTURES("Update Textures");
+static LLTrace::BlockTimerStatHandle FTM_UPDATE_DYNAMIC_TEXTURES("Update Dynamic Textures");
 static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images");
 static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_CLASS("Class");
 static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_BUMP("Image Update Bump");
@@ -590,7 +590,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
 	{
 		LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures");
-		LL_RECORD_BLOCK_TIME(FTM_UPDATE_TEXTURES);
+		LL_RECORD_BLOCK_TIME(FTM_UPDATE_DYNAMIC_TEXTURES);
 		if (LLViewerDynamicTexture::updateAllInstances())
 		{
 			gGL.setColorMask(true, true);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 6a72f243569..79585378563 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -779,8 +779,8 @@ static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMedi
 static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE("Update Media");
 static LLTrace::BlockTimerStatHandle FTM_MEDIA_SPARE_IDLE("Spare Idle");
 static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE_INTEREST("Update/Interest");
-static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT("Sort");
-static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT2("Sort 2");
+static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT("Media Sort");
+static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT2("Media Sort 2");
 static LLTrace::BlockTimerStatHandle FTM_MEDIA_MISC("Misc");
 
 
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 99903bfdf38..b98726900f8 100755
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -670,11 +670,11 @@ static LLTrace::BlockTimerStatHandle FTM_IMAGE_FETCH("Fetch");
 static LLTrace::BlockTimerStatHandle FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch");
 static LLTrace::BlockTimerStatHandle FTM_IMAGE_CREATE("Create");
 static LLTrace::BlockTimerStatHandle FTM_IMAGE_STATS("Stats");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_IMAGES("Update Images");
+static LLTrace::BlockTimerStatHandle FTM_UPDATE_TEXTURES("Update Textures");
 
 void LLViewerTextureList::updateImages(F32 max_time)
 {
-	LL_RECORD_BLOCK_TIME(FTM_UPDATE_IMAGES);
+	LL_RECORD_BLOCK_TIME(FTM_UPDATE_TEXTURES);
 	static BOOL cleared = FALSE;
 	if(gTeleportDisplay)
 	{
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c5148690a53..c2c981893a0 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -242,7 +242,7 @@ LLTrace::BlockTimerStatHandle FTM_RENDER_WL_SKY("Windlight Sky");
 LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA("Alpha Objects");
 LLTrace::BlockTimerStatHandle FTM_RENDER_CHARACTERS("Avatars");
 LLTrace::BlockTimerStatHandle FTM_RENDER_BUMP("Bump");
-LLTrace::BlockTimerStatHandle FTM_RENDER_MATERIALS("Materials");
+LLTrace::BlockTimerStatHandle FTM_RENDER_MATERIALS("Render Materials");
 LLTrace::BlockTimerStatHandle FTM_RENDER_FULLBRIGHT("Fullbright");
 LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW("Glow");
 LLTrace::BlockTimerStatHandle FTM_GEO_UPDATE("Geo Update");
-- 
GitLab