summaryrefslogtreecommitdiff
path: root/indra/llcommon/lockstatic.h
diff options
context:
space:
mode:
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) */