diff options
author | simon <none@none> | 2013-04-26 15:54:03 -0700 |
---|---|---|
committer | simon <none@none> | 2013-04-26 15:54:03 -0700 |
commit | 39638b0de3734fea2d112161a3289b67f7594ba3 (patch) | |
tree | 2728b27516d6cfe6ba8b329daa2cfd739298efdb /indra/llcommon | |
parent | b49f6e1e744e7650fbea77e5744343d223e962a3 (diff) |
Convert LLThreadSafeRefCount back to atomic ref counting. Reviewed by Kelly
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llthread.h | 90 |
1 files changed, 9 insertions, 81 deletions
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index a6eb14db9d..f51d985b5f 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -225,7 +225,6 @@ void LLThread::unlockData() // see llmemory.h for LLPointer<> definition -#if (1) // Old code - see comment below class LL_COMMON_API LLThreadSafeRefCount { public: @@ -243,99 +242,28 @@ public: LLThreadSafeRefCount(const LLThreadSafeRefCount&); LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref) { - if (sMutex) - { - sMutex->lock(); - } mRef = 0; - if (sMutex) - { - sMutex->unlock(); - } return *this; } - - void ref() { - if (sMutex) sMutex->lock(); mRef++; - if (sMutex) sMutex->unlock(); } - S32 unref() + void unref() { llassert(mRef >= 1); - if (sMutex) sMutex->lock(); - S32 res = --mRef; - if (sMutex) sMutex->unlock(); - if (0 == res) - { - delete this; - return 0; + 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 res; - } - S32 getNumRefs() const - { - return mRef; } -private: - S32 mRef; -}; - -#else - // New code - This was from https://bitbucket.org/lindenlab/viewer-cat/commits/b03bb43e4ead57f904cb3c1e9745dc8460de6efc - // and attempts - -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++; - } - - S32 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--; // Simon: why not if (mRef == 1) delete this; ? There still seems to be a window where mRef could be modified - if (mRef == 0) - delete this; - if (sMutex) sMutex->unlock(); - return 0; - } - return --mRef; - } S32 getNumRefs() const { const S32 currentVal = mRef.CurrentValue(); @@ -345,7 +273,7 @@ public: private: LLAtomic32< S32 > mRef; }; -#endif // new code + /** * intrusive pointer support for LLThreadSafeRefCount |