diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2019-12-03 20:44:26 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2020-03-25 15:28:17 -0400 |
commit | 1f7335fde34abdb9889e0c7b437fc02870570fcf (patch) | |
tree | e777146b49b4f0a13f642c9d7914e25ba42bc713 /indra/llcommon/llinstancetracker.h | |
parent | 794072c1415e986b95cab65f8217857263d7468a (diff) |
DRTVWR-494: Extract LockStatic as a standalone template class.
The pattern of requiring a lock to permit *any* access to a static instance of
something seems generally useful. Break out lockstatic.h; recast
LLInstanceTracker to use it.
Moving LockStatic to an external template class instead of a nested class in
LLInstanceTrackerBase leaves LLInstanceTrackerBase pretty empty. Get rid of it.
And *that* means we can move the definition of the StaticData used by each
LLInstanceTracker specialization into the class itself, rather than having to
define it beforehand in namespace LLInstanceTrackerStuff.
Diffstat (limited to 'indra/llcommon/llinstancetracker.h')
-rw-r--r-- | indra/llcommon/llinstancetracker.h | 98 |
1 files changed, 18 insertions, 80 deletions
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 272ad8086e..cfb40c25f0 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -41,64 +41,20 @@ #include <boost/iterator/indirect_iterator.hpp> #include <boost/iterator/filter_iterator.hpp> +#include "lockstatic.h" + /***************************************************************************** -* LLInstanceTrackerBase +* StaticBase *****************************************************************************/ -/** - * 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. - */ namespace LLInstanceTrackerStuff { struct StaticBase { // We need to be able to lock static data while manipulating it. - typedef std::mutex mutex_t; - mutex_t mMutex; + std::mutex mMutex; }; } // namespace LLInstanceTrackerStuff -template <class Static> -class LL_COMMON_API LLInstanceTrackerBase -{ -protected: - typedef Static StaticData; - - // Instantiate this class to obtain a pointer to the canonical static - // instance of class Static while holding a lock on that instance. Use of - // Static::mMutex presumes either that Static is derived from StaticBase, - // or that Static declares some other suitable mMutex. - class LockStatic - { - typedef std::unique_lock<decltype(Static::mMutex)> lock_t; - public: - LockStatic(): - mData(getStatic()), - mLock(mData->mMutex) - {} - Static* get() const { return mData; } - operator Static*() const { return get(); } - Static* operator->() const { return get(); } - // sometimes we must explicitly unlock... - void unlock() - { - // but once we do, access is no longer permitted - mData = nullptr; - mLock.unlock(); - } - protected: - Static* mData; - lock_t mLock; - private: - Static* getStatic() - { - static Static sData; - return &sData; - } - }; -}; - /***************************************************************************** * LLInstanceTracker with key *****************************************************************************/ @@ -108,29 +64,20 @@ enum EInstanceTrackerAllowKeyCollisions LLInstanceTrackerReplaceOnCollision }; -namespace LLInstanceTrackerStuff -{ - template <typename KEY, typename VALUE> - struct StaticMap: public StaticBase - { - typedef std::map<KEY, VALUE> InstanceMap; - InstanceMap mMap; - }; -} // LLInstanceTrackerStuff - /// 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 template<typename T, typename KEY = void, EInstanceTrackerAllowKeyCollisions KEY_COLLISION_BEHAVIOR = LLInstanceTrackerErrorOnCollision> -class LLInstanceTracker : - public LLInstanceTrackerBase<LLInstanceTrackerStuff::StaticMap<KEY, std::shared_ptr<T>>> +class LLInstanceTracker { - typedef LLInstanceTrackerBase<LLInstanceTrackerStuff::StaticMap<KEY, std::shared_ptr<T>>> super; - using typename super::StaticData; - using typename super::LockStatic; - typedef typename StaticData::InstanceMap InstanceMap; + typedef std::map<KEY, std::shared_ptr<T>> InstanceMap; + struct StaticData: public LLInstanceTrackerStuff::StaticBase + { + InstanceMap mMap; + }; + typedef llthread::LockStatic<StaticData> LockStatic; public: // snapshot of std::pair<const KEY, std::shared_ptr<T>> pairs @@ -334,16 +281,6 @@ private: /***************************************************************************** * LLInstanceTracker without key *****************************************************************************/ -namespace LLInstanceTrackerStuff -{ - template <typename VALUE> - struct StaticSet: public StaticBase - { - typedef std::set<VALUE> InstanceSet; - InstanceSet mSet; - }; -} // LLInstanceTrackerStuff - // TODO: // - For the case of omitted KEY template parameter, consider storing // std::map<T*, std::shared_ptr<T>> instead of std::set<std::shared_ptr<T>>. @@ -359,13 +296,14 @@ namespace LLInstanceTrackerStuff /// explicit specialization for default case where KEY is void /// use a simple std::set<T*> template<typename T, EInstanceTrackerAllowKeyCollisions KEY_COLLISION_BEHAVIOR> -class LLInstanceTracker<T, void, KEY_COLLISION_BEHAVIOR> : - public LLInstanceTrackerBase<LLInstanceTrackerStuff::StaticSet<std::shared_ptr<T>>> +class LLInstanceTracker<T, void, KEY_COLLISION_BEHAVIOR> { - typedef LLInstanceTrackerBase<LLInstanceTrackerStuff::StaticSet<std::shared_ptr<T>>> super; - using typename super::StaticData; - using typename super::LockStatic; - typedef typename StaticData::InstanceSet InstanceSet; + typedef std::set<std::shared_ptr<T>> InstanceSet; + struct StaticData: public LLInstanceTrackerStuff::StaticBase + { + InstanceSet mSet; + }; + typedef llthread::LockStatic<StaticData> LockStatic; public: /** |