summaryrefslogtreecommitdiff
path: root/indra/llcommon/llapr.h
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-09-24 18:56:01 -0700
committerRichard Linden <none@none>2012-09-24 18:56:01 -0700
commitadeeabfc13c91dc99a1ea1949cd2f820c4150995 (patch)
tree641a7bcfe966c1994f1461a1672e7a5193023ff8 /indra/llcommon/llapr.h
parent735fde8c742188d019e41faf26ff67aab6a24d25 (diff)
SH-3275 WIP Run viewer metrics for object update messages
moved LLThreadLocalPtr to llapr fixed various startup race conditions for LLThreadLocalPtr
Diffstat (limited to 'indra/llcommon/llapr.h')
-rw-r--r--indra/llcommon/llapr.h117
1 files changed, 117 insertions, 0 deletions
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index af33ce666f..eb0bf627a0 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -49,6 +49,7 @@
#include "apr_signal.h"
#include "apr_atomic.h"
#include "llstring.h"
+#include "llinstancetracker.h"
extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
extern apr_thread_mutex_t* gCallStacksLogMutexp;
@@ -255,6 +256,122 @@ public:
//*******************************************************************************************************************************
};
+class LLThreadLocalPtrBase : LLInstanceTracker<LLThreadLocalPtrBase>
+{
+public:
+ LLThreadLocalPtrBase(void (*cleanup_func)(void*) );
+ LLThreadLocalPtrBase(const LLThreadLocalPtrBase& other);
+ ~LLThreadLocalPtrBase();
+
+protected:
+ friend void LL_COMMON_API ll_init_apr();
+ void set(void* value);
+
+ LL_FORCE_INLINE void* get()
+ {
+ void* ptr;
+ //apr_status_t result =
+ apr_threadkey_private_get(&ptr, mThreadKey);
+ //if (result != APR_SUCCESS)
+ //{
+ // ll_apr_warn_status(s);
+ // llerrs << "Failed to get thread local data" << llendl;
+ //}
+ return ptr;
+ }
+
+ LL_FORCE_INLINE const void* get() const
+ {
+ void* ptr;
+ //apr_status_t result =
+ apr_threadkey_private_get(&ptr, mThreadKey);
+ //if (result != APR_SUCCESS)
+ //{
+ // ll_apr_warn_status(s);
+ // llerrs << "Failed to get thread local data" << llendl;
+ //}
+ return ptr;
+ }
+
+ void initStorage();
+
+ void destroyStorage();
+
+ static void initAllThreadLocalStorage();
+
+private:
+ void (*mCleanupFunc)(void*);
+ apr_threadkey_t* mThreadKey;
+ static bool sInitialized;
+};
+
+template <typename T>
+class LLThreadLocalPtr : public LLThreadLocalPtrBase
+{
+public:
+
+ LLThreadLocalPtr()
+ : LLThreadLocalPtrBase(&cleanup)
+ {}
+
+ LLThreadLocalPtr(T* value)
+ : LLThreadLocalPtrBase(&cleanup)
+ {
+ set(value);
+ }
+
+
+ LLThreadLocalPtr(const LLThreadLocalPtr<T>& other)
+ : LLThreadLocalPtrBase(other, &cleanup)
+ {
+ set(other.get());
+ }
+
+ T* get()
+ {
+ return (T*)LLThreadLocalPtrBase::get();
+ }
+
+ const T* get() const
+ {
+ return (const T*)LLThreadLocalPtrBase::get();
+ }
+
+ T* operator -> ()
+ {
+ return (T*)get();
+ }
+
+ const T* operator -> () const
+ {
+ return (T*)get();
+ }
+
+ T& operator*()
+ {
+ return *(T*)get();
+ }
+
+ const T& operator*() const
+ {
+ return *(T*)get();
+ }
+
+ LLThreadLocalPtr<T>& operator = (T* value)
+ {
+ set((void*)value);
+ return *this;
+ }
+
+private:
+
+ static void cleanup(void* ptr)
+ {
+ delete reinterpret_cast<T*>(ptr);
+ }
+
+};
+
/**
* @brief Function which appropriately logs error or remains quiet on
* APR_SUCCESS.