diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 2147b668b..2fe048b4e 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -63,7 +63,7 @@ //---------------------------------------------------------------------------- #if !LL_DARWIN -U32 ll_thread_local sThreadID = 0; +U32 ll_thread_local local_thread_ID = 0; #endif U32 LLThread::sIDIter = 0; @@ -89,7 +89,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap LLThread *threadp = (LLThread *)datap; #if !LL_DARWIN - sThreadID = threadp->mID; + local_thread_ID = threadp->mID; #endif // Create a thread local data. @@ -118,7 +118,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap LLThread::LLThread(std::string const& name) : - mPaused(FALSE), + mPaused(false), mName(name), mAPRThreadp(NULL), mStatus(STOPPED), @@ -213,7 +213,7 @@ void LLThread::pause() if (!mPaused) { // this will cause the thread to stop execution as soon as checkPause() is called - mPaused = 1; // Does not need to be atomic since this is only set/unset from the main thread + mPaused = true; // Does not need to be atomic since this is only set/unset from the main thread } } @@ -221,7 +221,7 @@ void LLThread::unpause() { if (mPaused) { - mPaused = 0; + mPaused = false; } wake(); // wake up the thread if necessary @@ -301,7 +301,7 @@ void LLThread::wakeLocked() #ifdef SHOW_ASSERT // This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. static apr_os_thread_t main_thread_id; -LL_COMMON_API bool is_main_thread() { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); } +LL_COMMON_API bool is_main_thread(void) { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); } #endif // The thread private handle to access the LLThreadLocalData instance. @@ -393,12 +393,18 @@ void LLCondition::broadcast() } //============================================================================ +LLMutexBase::LLMutexBase() : + mLockingThread(NO_THREAD), + mCount(0) +{ +} + void LLMutexBase::lock() { #if LL_DARWIN if (mLockingThread == LLThread::currentID()) #else - if (mLockingThread == sThreadID) + if (mLockingThread == local_thread_ID) #endif { //redundant lock mCount++; @@ -407,18 +413,10 @@ void LLMutexBase::lock() apr_thread_mutex_lock(mAPRMutexp); -#if MUTEX_DEBUG - // Have to have the lock before we can access the debug info - U32 id = LLThread::currentID(); - if (mIsLocked[id] != FALSE) - llerrs << "Already locked in Thread: " << id << llendl; - mIsLocked[id] = TRUE; -#endif - #if LL_DARWIN mLockingThread = LLThread::currentID(); #else - mLockingThread = sThreadID; + mLockingThread = local_thread_ID; #endif } @@ -429,35 +427,11 @@ void LLMutexBase::unlock() mCount--; return; } - -#if MUTEX_DEBUG - // Access the debug info while we have the lock - U32 id = LLThread::currentID(); - if (mIsLocked[id] != TRUE) - llerrs << "Not locked in Thread: " << id << llendl; - mIsLocked[id] = FALSE; -#endif - mLockingThread = NO_THREAD; + apr_thread_mutex_unlock(mAPRMutexp); } -bool LLMutexBase::isLocked() -{ - if (!tryLock()) - { - return true; - } - apr_thread_mutex_unlock(mAPRMutexp); - return false; -} - -U32 LLMutexBase::lockingThread() const -{ - return mLockingThread; -} - -//============================================================================ //---------------------------------------------------------------------------- //static diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 891c0a072..f0e4f39f5 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -97,7 +97,7 @@ public: // Called from MAIN THREAD. void pause(); void unpause(); - bool isPaused() { return isStopped() || mPaused == TRUE; } + bool isPaused() { return isStopped() || mPaused; } // Cause the thread to wake up and check its condition void wake(); @@ -117,7 +117,7 @@ public: U32 getID() const { return mID; } private: - BOOL mPaused; + bool mPaused; // static function passed to APR thread creation routine static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap); @@ -159,6 +159,16 @@ protected: //============================================================================ +#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) + +#ifdef MUTEX_DEBUG +// We really shouldn't be using recursive locks. Make sure of that in debug mode. +#define MUTEX_FLAG APR_THREAD_MUTEX_UNNESTED +#else +// Use the fastest platform-optimal lock behavior (can be recursive or non-recursive). +#define MUTEX_FLAG APR_THREAD_MUTEX_DEFAULT +#endif + class LL_COMMON_API LLMutexBase { public: @@ -167,15 +177,17 @@ public: NO_THREAD = 0xFFFFFFFF } e_locking_thread; - LLMutexBase() : mLockingThread(NO_THREAD), mCount(0) {} + LLMutexBase() ; void lock(); //blocks void unlock(); // Returns true if lock was obtained successfully. bool tryLock() { return !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)); } - bool isLocked(); // non-blocking, but does do a lock/unlock so not free - U32 lockingThread() const; //get ID of locking thread + // non-blocking, but does do a lock/unlock so not free + bool isLocked() { bool is_not_locked = tryLock(); if (is_not_locked) unlock(); return !is_not_locked; } + // get ID of locking thread + U32 lockingThread() const { return mLockingThread; } protected: // mAPRMutexp is initialized and uninitialized in the derived class. @@ -189,11 +201,12 @@ class LL_COMMON_API LLMutex : public LLMutexBase public: LLMutex(LLAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent) { - apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mPool()); + apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mPool()); } ~LLMutex() { - llassert(!isLocked()); // better not be locked! + //this assertion erroneously triggers whenever an LLCondition is destroyed + //llassert(!isLocked()); // better not be locked! apr_thread_mutex_destroy(mAPRMutexp); mAPRMutexp = NULL; } @@ -215,7 +228,7 @@ class LL_COMMON_API LLMutexRootPool : public LLMutexBase public: LLMutexRootPool(void) { - apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mRootPool()); + apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mRootPool()); } ~LLMutexRootPool() {