summaryrefslogtreecommitdiff
path: root/indra/llcommon/llinstancetracker.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llinstancetracker.h')
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llinstancetracker.h62
1 files changed, 37 insertions, 25 deletions
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 34d841a4e0..55187d8325 100644..100755
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -43,24 +43,10 @@
* semantics: one instance per process, rather than one instance per module as
* sometimes happens with data simply declared static.
*/
-class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
+class LL_COMMON_API LLInstanceTrackerBase
{
protected:
- /// Get a process-unique void* pointer slot for the specified type_info
- static void * & getInstances(std::type_info const & info);
- /// Find or create a STATICDATA instance for the specified TRACKED class.
- /// STATICDATA must be default-constructible.
- template<typename STATICDATA, class TRACKED>
- static STATICDATA& getStatic()
- {
- void *& instances = getInstances(typeid(TRACKED));
- if (! instances)
- {
- instances = new STATICDATA;
- }
- return *static_cast<STATICDATA*>(instances);
- }
/// It's not essential to derive your STATICDATA (for use with
/// getStatic()) from StaticBase; it's just that both known
@@ -74,6 +60,8 @@ protected:
};
};
+LL_COMMON_API void assert_main_thread();
+
/// 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
@@ -81,14 +69,18 @@ protected:
template<typename T, typename KEY = T*>
class LLInstanceTracker : public LLInstanceTrackerBase
{
- typedef LLInstanceTracker<T, KEY> MyT;
+ typedef LLInstanceTracker<T, KEY> self_t;
typedef typename std::map<KEY, T*> InstanceMap;
struct StaticData: public StaticBase
{
InstanceMap sMap;
};
- static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
- static InstanceMap& getMap_() { return getStatic().sMap; }
+ static StaticData& getStatic() { static StaticData sData; return sData;}
+ static InstanceMap& getMap_()
+ {
+ // assert_main_thread(); fwiw this class is not thread safe, and it used by multiple threads. Bad things happen.
+ return getStatic().sMap;
+ }
public:
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
@@ -167,8 +159,9 @@ public:
static T* getInstance(const KEY& k)
{
- typename InstanceMap::const_iterator found = getMap_().find(k);
- return (found == getMap_().end()) ? NULL : found->second;
+ const InstanceMap& map(getMap_());
+ typename InstanceMap::const_iterator found = map.find(k);
+ return (found == map.end()) ? NULL : found->second;
}
static instance_iter beginInstances()
@@ -209,6 +202,9 @@ protected:
virtual const KEY& getKey() const { return mInstanceKey; }
private:
+ LLInstanceTracker( const LLInstanceTracker& );
+ const LLInstanceTracker& operator=( const LLInstanceTracker& );
+
void add_(KEY key)
{
mInstanceKey = key;
@@ -216,7 +212,11 @@ private:
}
void remove_()
{
- getMap_().erase(mInstanceKey);
+ typename InstanceMap::iterator iter = getMap_().find(mInstanceKey);
+ if (iter != getMap_().end())
+ {
+ getMap_().erase(iter);
+ }
}
private:
@@ -228,19 +228,31 @@ private:
template<typename T>
class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
{
- typedef LLInstanceTracker<T, T*> MyT;
+ typedef LLInstanceTracker<T, T*> self_t;
typedef typename std::set<T*> InstanceSet;
struct StaticData: public StaticBase
{
InstanceSet sSet;
};
- static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+ static StaticData& getStatic() { static StaticData sData; return sData; }
static InstanceSet& getSet_() { return getStatic().sSet; }
public:
- /// for completeness of analogy with the generic implementation
- static T* getInstance(T* k) { return k; }
+ /**
+ * Does a particular instance still exist? Of course, if you already have
+ * a T* in hand, you need not call getInstance() to @em locate the
+ * instance -- unlike the case where getInstance() accepts some kind of
+ * key. Nonetheless this method is still useful to @em validate a
+ * particular T*, since each instance's destructor removes itself from the
+ * underlying set.
+ */
+ static T* getInstance(T* k)
+ {
+ const InstanceSet& set(getSet_());
+ typename InstanceSet::const_iterator found = set.find(k);
+ return (found == set.end())? NULL : *found;
+ }
static S32 instanceCount() { return getSet_().size(); }
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>