From 391ac367d6922f30bf3a186bc15e1fc38366eecf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 19 Nov 2013 17:40:44 -0800 Subject: 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 ++++---- 3 files changed, 38 insertions(+), 22 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 3107415ccf..cfe690b9ec 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 +template class LLInstanceTracker : public LLInstanceTrackerBase { typedef LLInstanceTracker self_t; @@ -192,7 +192,7 @@ public: } protected: - LLInstanceTracker(KEY key) + LLInstanceTracker(const KEY& key) { // make sure static data outlives all instances getStatic(); @@ -211,28 +211,44 @@ private: 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(this); + break; + } + default: + break; + } } else - { + { // new key map.insert(insertion_point_it, std::make_pair(key, static_cast(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 @@ private: /// explicit specialization for default case where KEY is void /// use a simple std::set -template -class LLInstanceTracker : public LLInstanceTrackerBase +template +class LLInstanceTracker : public LLInstanceTrackerBase { typedef LLInstanceTracker self_t; typedef typename std::set InstanceSet; diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 8b67dd8f44..7e811efe71 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -69,10 +69,10 @@ protected: template class StatType : public StatBase, - public LLInstanceTracker, std::string, LLInstanceTrackerAllowKeyCollisions> + public LLInstanceTracker, std::string> { public: - typedef LLInstanceTracker, std::string, LLInstanceTrackerAllowKeyCollisions> instance_tracker_t; + typedef LLInstanceTracker, 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 dfa037d7c0..42fad8a793 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 }; -- cgit v1.2.3