summaryrefslogtreecommitdiff
path: root/indra/llcommon/lockstatic.h
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2019-12-03 20:44:26 -0500
committerNat Goodspeed <nat@lindenlab.com>2020-03-25 15:28:17 -0400
commit1f7335fde34abdb9889e0c7b437fc02870570fcf (patch)
treee777146b49b4f0a13f642c9d7914e25ba42bc713 /indra/llcommon/lockstatic.h
parent794072c1415e986b95cab65f8217857263d7468a (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/lockstatic.h')
-rw-r--r--indra/llcommon/lockstatic.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/indra/llcommon/lockstatic.h b/indra/llcommon/lockstatic.h
new file mode 100644
index 0000000000..5f08742cae
--- /dev/null
+++ b/indra/llcommon/lockstatic.h
@@ -0,0 +1,56 @@
+/**
+ * @file lockstatic.h
+ * @author Nat Goodspeed
+ * @date 2019-12-03
+ * @brief LockStatic class provides mutex-guarded access to the specified
+ * static data.
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Copyright (c) 2019, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LOCKSTATIC_H)
+#define LL_LOCKSTATIC_H
+
+#include "mutex.h" // std::unique_lock
+
+namespace llthread
+{
+
+// Instantiate this template to obtain a pointer to the canonical static
+// instance of Static while holding a lock on that instance. Use of
+// Static::mMutex presumes that Static declares some suitable mMutex.
+template <typename Static>
+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;
+ }
+};
+
+} // llthread namespace
+
+#endif /* ! defined(LL_LOCKSTATIC_H) */