diff options
Diffstat (limited to 'indra/llcommon/llinstancetracker.h')
-rw-r--r-- | indra/llcommon/llinstancetracker.h | 71 |
1 files changed, 19 insertions, 52 deletions
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index c31f579f30..361182380a 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -38,57 +38,15 @@ #include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/indirect_iterator.hpp> -enum InstanceTrackType -{ - InstanceTrackType_LLEventAPI, - InstanceTrackType_LLEventTimer, - InstanceTrackType_NamedTimer, - InstanceTrackType_DeclareTimer, - InstanceTrackType_LLLeap, - InstanceTrackType_LLGLNamePool, - InstanceTrackType_LLConsole, - InstanceTrackType_LLFloater, - InstanceTrackType_LLFloaterWebContent, - InstanceTrackType_LLLayoutStack, - InstanceTrackType_LLNotificationContext, - InstanceTrackType_LLWindow, - InstanceTrackType_LLControlGroup, - InstanceTrackType_LLControlCache, - InstanceTrackType_LLMediaCtrl, - InstanceTrackType_LLNameListCtrl, - InstanceTrackType_LLToast, - InstanceTrackType_Keyed, // for integ tests - InstanceTrackType_Unkeyed, // for integ tests - kInstanceTrackTypeCount -}; - -#define INSTANCE_TRACKER(T) LLInstanceTracker< T, InstanceTrackType_##T > -#define INSTANCE_TRACKER_KEYED(T,K) LLInstanceTracker< T, InstanceTrackType_##T, K > - /** * Base class manages "class-static" data that must actually have singleton * 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); - static void * & getInstances(InstanceTrackType t); - - /// Find or create a STATICDATA instance for the specified TRACKED class. - /// STATICDATA must be default-constructible. - template<typename STATICDATA, class TRACKED, class INST, InstanceTrackType TRACKEDTYPE> - static STATICDATA& getStatic() - { - void *& instances = getInstances(TRACKEDTYPE); - 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 @@ -102,21 +60,27 @@ 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 /// @NOTE: see explicit specialization below for default KEY==T* case -template<typename T, enum InstanceTrackType TRACKED, typename KEY = T*> +template<typename T, typename KEY = T*> class LLInstanceTracker : public LLInstanceTrackerBase { - typedef LLInstanceTracker<T, TRACKED, 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, T, TRACKED>(); } - 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> @@ -238,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; @@ -254,16 +221,16 @@ private: /// explicit specialization for default case where KEY is T* /// use a simple std::set<T*> -template<typename T, enum InstanceTrackType TRACKED> -class LLInstanceTracker<T, TRACKED, T*> : public LLInstanceTrackerBase +template<typename T> +class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase { - typedef LLInstanceTracker<T, TRACKED, 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, T, TRACKED>(); } + static StaticData& getStatic() { static StaticData sData; return sData; } static InstanceSet& getSet_() { return getStatic().sSet; } public: |