summaryrefslogtreecommitdiff
path: root/indra/llcommon/llthread.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llthread.h')
-rw-r--r--indra/llcommon/llthread.h47
1 files changed, 30 insertions, 17 deletions
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 0d22bc863d..f51d985b5f 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -30,6 +30,7 @@
#include "llapp.h"
#include "llapr.h"
#include "apr_thread_cond.h"
+#include "boost/intrusive_ptr.hpp"
class LLThread;
class LLMutex;
@@ -250,26 +251,19 @@ public:
mRef++;
}
- S32 unref()
+ void unref()
{
- llassert(mRef >= 1);
- bool time_to_die = (mRef == 1);
- if (time_to_die)
- {
- if (sMutex) sMutex->lock();
- // Looks redundant, but is very much not
- // We need to check again once we've acquired the lock
- // so that two threads who get into the if in parallel
- // don't both attempt to the delete.
- //
- mRef--;
- if (mRef == 0)
- delete this;
- if (sMutex) sMutex->unlock();
- return 0;
+ 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;
}
- return --mRef;
}
+
S32 getNumRefs() const
{
const S32 currentVal = mRef.CurrentValue();
@@ -280,6 +274,23 @@ private:
LLAtomic32< S32 > mRef;
};
+
+/**
+ * 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(LLThreadSafeRefCount* p)
+ {
+ p->ref();
+ }
+
+ inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
+ {
+ p->unref();
+ }
+};
//============================================================================
// Simple responder for self destructing callbacks
@@ -294,4 +305,6 @@ public:
//============================================================================
+extern LL_COMMON_API void assert_main_thread();
+
#endif // LL_LLTHREAD_H