summaryrefslogtreecommitdiff
path: root/indra/llcommon/llinstancetracker.h
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-10-17 14:23:56 -0700
committerRichard Linden <none@none>2013-10-17 14:23:56 -0700
commit1beaedacadc8093c9df612992a873f9c89354bce (patch)
treea056537b11fb577b7dee9ed236a2616eb0989d9d /indra/llcommon/llinstancetracker.h
parent1c26d4265666cd232d38724ad6f1e32fd2dc2d34 (diff)
moved root timer to global variable
added flag to LLInstanceTracker to allow multiple values per key made StatType allow multiple values per key to eliminate block timer related crash
Diffstat (limited to 'indra/llcommon/llinstancetracker.h')
-rwxr-xr-xindra/llcommon/llinstancetracker.h27
1 files changed, 22 insertions, 5 deletions
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index f2b982c4c3..1385475444 100755
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -62,16 +62,22 @@ protected:
LL_COMMON_API void assert_main_thread();
+enum EInstanceTrackerAllowKeyCollisions
+{
+ InstanceTrackerAllowKeyCollisions,
+ InstanceTrackerDisallowKeyCollisions
+};
+
/// This mix-in class adds support for tracking all instances of the specified class parameter T
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
/// 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>
+template<typename T, typename KEY = void, EInstanceTrackerAllowKeyCollisions ALLOW_KEY_COLLISIONS = InstanceTrackerDisallowKeyCollisions>
class LLInstanceTracker : public LLInstanceTrackerBase
{
typedef LLInstanceTracker<T, KEY> self_t;
- typedef typename std::map<KEY, T*> InstanceMap;
+ typedef typename std::multimap<KEY, T*> InstanceMap;
struct StaticData: public StaticBase
{
InstanceMap sMap;
@@ -208,7 +214,18 @@ private:
void add_(KEY key)
{
mInstanceKey = key;
- getMap_()[key] = static_cast<T*>(this);
+ InstanceMap& map = getMap_();
+ InstanceMap::iterator insertion_point_it = map.lower_bound(key);
+ if (ALLOW_KEY_COLLISIONS == InstanceTrackerDisallowKeyCollisions
+ && 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;
+ }
+ else
+ {
+ map.insert(insertion_point_it, std::make_pair(key, static_cast<T*>(this)));
+ }
}
void remove_()
{
@@ -225,8 +242,8 @@ private:
/// explicit specialization for default case where KEY is void
/// use a simple std::set<T*>
-template<typename T>
-class LLInstanceTracker<T, void> : public LLInstanceTrackerBase
+template<typename T, EInstanceTrackerAllowKeyCollisions ALLOW_KEY_COLLISIONS>
+class LLInstanceTracker<T, void, ALLOW_KEY_COLLISIONS> : public LLInstanceTrackerBase
{
typedef LLInstanceTracker<T, void> self_t;
typedef typename std::set<T*> InstanceSet;