summaryrefslogtreecommitdiff
path: root/indra/llcommon/llrefcount.h
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-11-06 17:22:04 -0800
committerRichard Linden <none@none>2013-11-06 17:22:04 -0800
commitfe518bde8e6db65d3d6b178c200410b1346639a4 (patch)
treed738e12f8391a675d36aae9d59ced8104846008c /indra/llcommon/llrefcount.h
parentea1e1b0925b386cf83178539b8eae9e25c573548 (diff)
parentd9d46d908c0573dbcd45ec2a1bea56966823343b (diff)
merge with release
Diffstat (limited to 'indra/llcommon/llrefcount.h')
-rwxr-xr-xindra/llcommon/llrefcount.h79
1 files changed, 75 insertions, 4 deletions
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 32ae15435a..72011d04a0 100755
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -28,6 +28,8 @@
#include <boost/noncopyable.hpp>
#include <boost/intrusive_ptr.hpp>
+#include "llmutex.h"
+#include "llapr.h"
#define LL_REF_COUNT_DEBUG 0
#if LL_REF_COUNT_DEBUG
@@ -61,7 +63,7 @@ public:
inline S32 unref() const
{
llassert(mRef >= 1);
- if (0 == --mRef)
+ if (0 == --mRef)
{
delete this;
return 0;
@@ -87,22 +89,91 @@ private:
#endif
};
+
+//============================================================================
+
+// see llmemory.h for LLPointer<> definition
+
+class LL_COMMON_API LLThreadSafeRefCount
+{
+public:
+ static void initThreadSafeRefCount(); // creates sMutex
+ static void cleanupThreadSafeRefCount(); // destroys sMutex
+
+private:
+ static LLMutex* sMutex;
+
+protected:
+ virtual ~LLThreadSafeRefCount(); // use unref()
+
+public:
+ LLThreadSafeRefCount();
+ LLThreadSafeRefCount(const LLThreadSafeRefCount&);
+ LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
+ {
+ mRef = 0;
+ return *this;
+ }
+
+ void ref()
+ {
+ mRef++;
+ }
+
+ void unref()
+ {
+ llassert(mRef >= 1);
+ if ((--mRef) == 0) // See note in llapr.h on atomic decrement operator return value.
+ {
+ // If we hit zero, the caller should be the only smart pointer owning the object and we can delete it.
+ // It is technically possible for a vanilla pointer to mess this up, or another thread to
+ // jump in, find this object, create another smart pointer and end up dangling, but if
+ // the code is that bad and not thread-safe, it's trouble already.
+ delete this;
+ }
+ }
+
+ S32 getNumRefs() const
+ {
+ const S32 currentVal = mRef.CurrentValue();
+ return currentVal;
+ }
+
+private:
+ LLAtomic32< S32 > mRef;
+};
+
/**
* intrusive pointer support
* this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
*/
+/**
+ * intrusive pointer support for LLThreadSafeRefCount
+ * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
+ */
namespace boost
{
- inline void intrusive_ptr_add_ref(LLRefCount* p)
+ inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
{
p->ref();
}
- inline void intrusive_ptr_release(LLRefCount* p)
+ inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
{
- p->unref();
+ p->unref();
+ }
+
+ inline void intrusive_ptr_add_ref(LLRefCount* p)
+ {
+ p->ref();
+ }
+
+ inline void intrusive_ptr_release(LLRefCount* p)
+ {
+ p->unref();
}
};
+
#endif