From 03c79ba6cbfd8c62a6a05fff1c8406650226f87c Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 5 Apr 2018 00:35:23 +0200 Subject: [PATCH 01/10] Remove apr from LLAtomic32 and rather use std::atomic and thus rename the class to a more generic name of LLAtomic The apr atomics had been problematic as no one ever did bother to call apr_atomic_init. This: - either did lead to crashes if apr was compiled to use a mutex for thread safe variable intialisation - or initialisation was okay, but apr did not synchronize setting the *pointer to a value. --- indra/llcommon/llapp.h | 5 ++-- indra/llcommon/llapr.h | 35 ++++++++++++++-------------- indra/llcommon/llinstancetracker.cpp | 7 +++--- indra/llcommon/llinstancetracker.h | 3 ++- indra/llcommon/llqueuedthread.h | 4 ++-- indra/llcommon/llrefcount.h | 2 +- indra/llmessage/llproxy.h | 2 +- indra/newview/lltexturecache.h | 2 +- 8 files changed, 31 insertions(+), 29 deletions(-) diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index acd829d864..60a4d19a00 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -30,9 +30,10 @@ #include #include "llrun.h" #include "llsd.h" +#include // Forward declarations -template class LLAtomic32; -typedef LLAtomic32 LLAtomicU32; +template class LLAtomic; +typedef LLAtomic LLAtomicU32; class LLErrorThread; class LLLiveFile; #if LL_LINUX diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 1ac5c4e9b2..5ff9082e30 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -39,7 +39,7 @@ #include "apr_thread_mutex.h" #include "apr_getopt.h" #include "apr_signal.h" -#include "apr_atomic.h" +#include #include "llstring.h" @@ -164,32 +164,33 @@ protected: apr_thread_mutex_t* mMutex; }; -template class LLAtomic32 +template class LLAtomic { public: - LLAtomic32() {}; - LLAtomic32(Type x) {apr_atomic_set32(&mData, apr_uint32_t(x)); }; - ~LLAtomic32() {}; + LLAtomic() {}; + LLAtomic( Type x ) { mData.store( x ); }; + ~LLAtomic() {}; - operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); } + operator const Type() { return (Type)mData.load(); } - Type CurrentValue() const { apr_uint32_t data = apr_atomic_read32(const_cast< volatile apr_uint32_t* >(&mData)); return Type(data); } + Type CurrentValue() const { return (Type)mData; } - Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); } - void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); } - void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); } - Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++ - Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise) + Type operator =( Type x) { mData.store( x ); return Type(mData); } + void operator -=(Type x) { mData -= x; } + void operator +=(Type x) { mData += x; } + Type operator ++(int) { return ++mData; } // Type++ + Type operator --(int) { return --mData; } // approximately --Type (0 if final is 0, non-zero otherwise) - Type operator ++() { return apr_atomic_inc32(&mData); } // Type++ - Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise) + Type operator ++() { return mData++; } // Type++ + Type operator --() { return mData--; } // approximately --Type (0 if final is 0, non-zero otherwise) private: - volatile apr_uint32_t mData; + AtomicType mData; }; -typedef LLAtomic32 LLAtomicU32; -typedef LLAtomic32 LLAtomicS32; +typedef LLAtomic LLAtomicU32; +typedef LLAtomic LLAtomicS32; +typedef LLAtomic LLAtomicBool; // File IO convenience functions. // Returns NULL if the file fails to open, sets *sizep to file size if not NULL diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp index 11fc53f8c8..6352cac99c 100644 --- a/indra/llcommon/llinstancetracker.cpp +++ b/indra/llcommon/llinstancetracker.cpp @@ -36,17 +36,16 @@ void LLInstanceTrackerBase::StaticBase::incrementDepth() { - apr_atomic_inc32(&sIterationNestDepth); + ++sIterationNestDepth; } void LLInstanceTrackerBase::StaticBase::decrementDepth() { llassert(sIterationNestDepth); - apr_atomic_dec32(&sIterationNestDepth); + --sIterationNestDepth; } U32 LLInstanceTrackerBase::StaticBase::getDepth() { - apr_uint32_t data = apr_atomic_read32(&sIterationNestDepth); - return data; + return sIterationNestDepth.load(); } diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 910c8dbd99..c90dbfcabd 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -31,6 +31,7 @@ #include #include +#include #include "llstringtable.h" #include #include @@ -81,7 +82,7 @@ protected: void decrementDepth(); U32 getDepth(); private: - U32 sIterationNestDepth; + std::atomic_uint32_t sIterationNestDepth; }; }; diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index d3704b0fe2..e97fb36b7b 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -128,7 +128,7 @@ public: }; protected: - LLAtomic32 mStatus; + LLAtomic > mStatus; U32 mPriority; U32 mFlags; }; @@ -198,7 +198,7 @@ public: protected: BOOL mThreaded; // if false, run on main thread and do updates during update() BOOL mStarted; // required when mThreaded is false to call startThread() from update() - LLAtomic32 mIdleThread; // request queue is empty (or we are quitting) and the thread is idle + LLAtomicBool mIdleThread; // request queue is empty (or we are quitting) and the thread is idle typedef std::set request_queue_t; request_queue_t mRequestQueue; diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 1107973569..09e4d09cd0 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -140,7 +140,7 @@ public: } private: - LLAtomic32< S32 > mRef; + LLAtomicS32 mRef; }; /** diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 688dff7c83..87891901ad 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -298,7 +298,7 @@ private: private: // Is the HTTP proxy enabled? Safe to read in any thread, but do not write directly. // Instead use enableHTTPProxy() and disableHTTPProxy() instead. - mutable LLAtomic32 mHTTPProxyEnabled; + mutable LLAtomicBool mHTTPProxyEnabled; // Mutex to protect shared members in non-main thread calls to applyProxySettings(). mutable LLMutex mProxyMutex; diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 95f9afc2bc..a536510cd3 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -221,7 +221,7 @@ private: typedef std::map size_map_t; size_map_t mTexturesSizeMap; S64 mTexturesSizeTotal; - LLAtomic32 mDoPurge; + LLAtomicBool mDoPurge; typedef std::map idx_entry_map_t; idx_entry_map_t mUpdatedEntryMap; From ef20e3f523a8f435b1f3d851b347dd56979d1b9f Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 5 Apr 2018 12:02:12 +0200 Subject: [PATCH 02/10] Replace ARP Mutex and Condition with std::mutx and std::conditional_variable --- indra/llcommon/llapr.cpp | 58 +++++----------- indra/llcommon/llapr.h | 22 ++++-- indra/llcommon/llerror.cpp | 5 +- indra/llcommon/llfixedbuffer.cpp | 3 +- indra/llcommon/llmemory.cpp | 2 +- indra/llcommon/llmutex.cpp | 67 ++++++------------- indra/llcommon/llmutex.h | 22 +++--- indra/llcommon/llqueuedthread.cpp | 2 +- indra/llcommon/llthread.cpp | 6 +- indra/llcommon/lluuid.cpp | 2 +- indra/llcommon/llworkerthread.cpp | 3 +- indra/llcorehttp/httpcommon.cpp | 4 +- indra/llimage/llimage.cpp | 2 +- indra/llimage/llimageworker.cpp | 2 +- indra/llmath/llvolumemgr.cpp | 2 +- indra/llmessage/llbuffer.cpp | 2 +- indra/llmessage/llproxy.cpp | 1 - indra/llmessage/llpumpio.h | 4 +- indra/llplugin/llpluginmessagepipe.cpp | 2 - indra/llplugin/llpluginprocessparent.cpp | 5 +- indra/llvfs/llvfs.cpp | 2 +- indra/newview/llappviewer.cpp | 2 +- .../newview/llfloaterconversationpreview.cpp | 1 - indra/newview/llfloatermodelpreview.cpp | 4 +- indra/newview/lllogchat.cpp | 4 +- indra/newview/llmeshrepository.cpp | 14 ++-- indra/newview/lltexturecache.cpp | 4 -- indra/newview/lltexturefetch.cpp | 3 - indra/newview/llviewermenufile.cpp | 2 +- indra/newview/llwatchdog.cpp | 2 +- 30 files changed, 101 insertions(+), 153 deletions(-) diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index d353d06de2..33c3d5db20 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -33,8 +33,8 @@ apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool. -apr_thread_mutex_t *gLogMutexp = NULL; -apr_thread_mutex_t *gCallStacksLogMutexp = NULL; +std::mutex *gLogMutexp = nullptr; +std::mutex *gCallStacksLogMutexp = nullptr; const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool @@ -49,9 +49,8 @@ void ll_init_apr() { apr_pool_create(&gAPRPoolp, NULL); - // Initialize the logging mutex - apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); - apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); + gLogMutexp = new std::mutex(); + gCallStacksLogMutexp = new std::mutex(); } if(!LLAPRFile::sAPRFilePoolp) @@ -75,22 +74,12 @@ void ll_cleanup_apr() LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL; - if (gLogMutexp) - { - // Clean up the logging mutex - - // All other threads NEED to be done before we clean up APR, so this is okay. - apr_thread_mutex_destroy(gLogMutexp); - gLogMutexp = NULL; - } - if (gCallStacksLogMutexp) - { - // Clean up the logging mutex - - // All other threads NEED to be done before we clean up APR, so this is okay. - apr_thread_mutex_destroy(gCallStacksLogMutexp); - gCallStacksLogMutexp = NULL; - } + // Clean up the logging mutex + // All other threads NEED to be done before we clean up APR, so this is okay. + delete gLogMutexp; + gLogMutexp = nullptr; + delete gCallStacksLogMutexp; + gCallStacksLogMutexp = nullptr; LLThreadLocalPointerBase::destroyAllThreadLocalStorage(); @@ -176,18 +165,14 @@ LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size if(!is_local) //not a local apr_pool, that is: shared by multiple threads. { apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex - apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool); + mMutexp = new std::mutex(); } } LLVolatileAPRPool::~LLVolatileAPRPool() { - //delete mutex - if(mMutexp) - { - apr_thread_mutex_destroy(mMutexp); - apr_pool_destroy(mMutexPool); - } + delete mMutexp; + mMutexp = nullptr; } // @@ -254,18 +239,12 @@ BOOL LLVolatileAPRPool::isFull() // // LLScopedLock // -LLScopedLock::LLScopedLock(apr_thread_mutex_t* mutex) : mMutex(mutex) +LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex) { if(mutex) { - if(ll_apr_warn_status(apr_thread_mutex_lock(mMutex))) - { - mLocked = false; - } - else - { - mLocked = true; - } + mutex->lock(); + mLocked = true; } else { @@ -282,10 +261,7 @@ void LLScopedLock::unlock() { if(mLocked) { - if(!ll_apr_warn_status(apr_thread_mutex_unlock(mMutex))) - { - mLocked = false; - } + mMutex->unlock(); } } diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 5ff9082e30..d08014b5ef 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -36,15 +36,25 @@ #include #include "llwin32headerslean.h" #include "apr_thread_proc.h" -#include "apr_thread_mutex.h" + #include "apr_getopt.h" #include "apr_signal.h" #include +#if LL_WINDOWS +#pragma warning(disable:4265) +#endif + +#include + +#if LL_WINDOWS +#pragma warning(default:4265) +#endif + #include "llstring.h" -extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; -extern apr_thread_mutex_t* gCallStacksLogMutexp; +extern LL_COMMON_API std::mutex* gLogMutexp; +extern std::mutex* gCallStacksLogMutexp; struct apr_dso_handle_t; /** @@ -120,7 +130,7 @@ private: S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating. - apr_thread_mutex_t *mMutexp; + std::mutex *mMutexp; apr_pool_t *mMutexPool; } ; @@ -142,7 +152,7 @@ public: * @param mutex An allocated APR mutex. If you pass in NULL, * this wrapper will not lock. */ - LLScopedLock(apr_thread_mutex_t* mutex); + LLScopedLock( std::mutex* mutex ); /** * @brief Destructor which unlocks the mutex if still locked. @@ -161,7 +171,7 @@ public: protected: bool mLocked; - apr_thread_mutex_t* mMutex; + std::mutex* mMutex; }; template class LLAtomic diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f31a054139..fdea42d08a 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1018,8 +1018,7 @@ namespace { const int MAX_RETRIES = 5; for (int attempts = 0; attempts < MAX_RETRIES; ++attempts) { - apr_status_t s = apr_thread_mutex_trylock(gLogMutexp); - if (!APR_STATUS_IS_EBUSY(s)) + if( gLogMutexp->try_lock() ) { mLocked = true; mOK = true; @@ -1041,7 +1040,7 @@ namespace { { if (mLocked) { - apr_thread_mutex_unlock(gLogMutexp); + gLogMutexp->unlock(); } } } diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp index d394f179fb..4b5cdbe288 100644 --- a/indra/llcommon/llfixedbuffer.cpp +++ b/indra/llcommon/llfixedbuffer.cpp @@ -30,8 +30,7 @@ LLFixedBuffer::LLFixedBuffer(const U32 max_lines) : LLLineBuffer(), - mMaxLines(max_lines), - mMutex(NULL) + mMaxLines(max_lines) { mTimer.reset(); } diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 049e962638..bcf30ff9a6 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -1122,7 +1122,7 @@ LLPrivateMemoryPool::LLPrivateMemoryPool(S32 type, U32 max_pool_size) : { if(type == STATIC_THREADED || type == VOLATILE_THREADED) { - mMutexp = new LLMutex(NULL) ; + mMutexp = new LLMutex() ; } for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index 9c13ef9e30..1090acd9fd 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -33,20 +33,11 @@ //============================================================================ -LLMutex::LLMutex(apr_pool_t *poolp) : - mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD) +LLMutex::LLMutex() : + mCount(0), mLockingThread(NO_THREAD) { - //if (poolp) - //{ - // mIsLocalPool = FALSE; - // mAPRPoolp = poolp; - //} - //else - { - mIsLocalPool = TRUE; - apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread - } - apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); + + mMutexp = new std::mutex(); } @@ -56,15 +47,8 @@ LLMutex::~LLMutex() //bad assertion, the subclass LLSignal might be "locked", and that's OK //llassert_always(!isLocked()); // better not be locked! #endif - if (ll_apr_is_initialized()) - { - apr_thread_mutex_destroy(mAPRMutexp); - if (mIsLocalPool) - { - apr_pool_destroy(mAPRPoolp); - } - } - mAPRMutexp = NULL; + delete mMutexp; + mMutexp = nullptr; } @@ -76,7 +60,7 @@ void LLMutex::lock() return; } - apr_thread_mutex_lock(mAPRMutexp); + mMutexp->lock(); #if MUTEX_DEBUG // Have to have the lock before we can access the debug info @@ -106,19 +90,18 @@ void LLMutex::unlock() #endif mLockingThread = NO_THREAD; - apr_thread_mutex_unlock(mAPRMutexp); + mMutexp->unlock(); } bool LLMutex::isLocked() { - apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp); - if (APR_STATUS_IS_EBUSY(status)) + if (!mMutexp->try_lock()) { return true; } else { - apr_thread_mutex_unlock(mAPRMutexp); + mMutexp->unlock(); return false; } } @@ -141,8 +124,7 @@ bool LLMutex::trylock() return true; } - apr_status_t status(apr_thread_mutex_trylock(mAPRMutexp)); - if (APR_STATUS_IS_EBUSY(status)) + if (!mMutexp->try_lock()) { return false; } @@ -161,44 +143,35 @@ bool LLMutex::trylock() //============================================================================ -LLCondition::LLCondition(apr_pool_t *poolp) : - LLMutex(poolp) +LLCondition::LLCondition() + { // base class (LLMutex) has already ensured that mAPRPoolp is set up. - - apr_thread_cond_create(&mAPRCondp, mAPRPoolp); + mCondp = new std::condition_variable(); } LLCondition::~LLCondition() { - apr_thread_cond_destroy(mAPRCondp); - mAPRCondp = NULL; + delete mCondp; + mCondp = nullptr; } void LLCondition::wait() { - if (!isLocked()) - { //mAPRMutexp MUST be locked before calling apr_thread_cond_wait - apr_thread_mutex_lock(mAPRMutexp); -#if MUTEX_DEBUG - // avoid asserts on destruction in non-release builds - U32 id = LLThread::currentID(); - mIsLocked[id] = TRUE; -#endif - } - apr_thread_cond_wait(mAPRCondp, mAPRMutexp); + std::unique_lock< std::mutex > lock( *mMutexp ); + mCondp->wait( lock ); } void LLCondition::signal() { - apr_thread_cond_signal(mAPRCondp); + mCondp->notify_one() ; } void LLCondition::broadcast() { - apr_thread_cond_broadcast(mAPRCondp); + mCondp->notify_all(); } diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index ea535cee86..566f37c66a 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -29,6 +29,16 @@ #include "stdtypes.h" +#if LL_WINDOWS +#pragma warning(disable:4265) +#endif + +#include +#include + +#if LL_WINDOWS +#pragma warning(default:4265) +#endif //============================================================================ #define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) @@ -37,9 +47,6 @@ #include #endif -struct apr_thread_mutex_t; -struct apr_pool_t; -struct apr_thread_cond_t; class LL_COMMON_API LLMutex { @@ -49,7 +56,7 @@ public: NO_THREAD = 0xFFFFFFFF } e_locking_thread; - LLMutex(apr_pool_t *apr_poolp = NULL); // NULL pool constructs a new pool for the mutex + LLMutex(); // NULL pool constructs a new pool for the mutex virtual ~LLMutex(); void lock(); // blocks @@ -60,11 +67,10 @@ public: U32 lockingThread() const; //get ID of locking thread protected: - apr_thread_mutex_t *mAPRMutexp; + std::mutex *mMutexp; mutable U32 mCount; mutable U32 mLockingThread; - apr_pool_t *mAPRPoolp; BOOL mIsLocalPool; #if MUTEX_DEBUG @@ -76,7 +82,7 @@ protected: class LL_COMMON_API LLCondition : public LLMutex { public: - LLCondition(apr_pool_t* apr_poolp); // Defaults to global pool, could use the thread pool as well. + LLCondition(); // Defaults to global pool, could use the thread pool as well. ~LLCondition(); void wait(); // blocks @@ -84,7 +90,7 @@ public: void broadcast(); protected: - apr_thread_cond_t* mAPRCondp; + std::condition_variable* mCondp; }; class LLMutexLock diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 8cef4293cd..8684ff4a87 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -36,10 +36,10 @@ LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded, bool should_pause) : LLThread(name), mThreaded(threaded), - mIdleThread(TRUE), mNextHandle(0), mStarted(FALSE) { + mIdleThread = true; if (mThreaded) { if(should_pause) diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 32e8ea9682..1e68124867 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -183,8 +183,8 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mIsLocalPool = TRUE; apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread } - mRunCondition = new LLCondition(mAPRPoolp); - mDataLock = new LLMutex(mAPRPoolp); + mRunCondition = new LLCondition(); + mDataLock = new LLMutex(); mLocalAPRFilePoolp = NULL ; } @@ -409,7 +409,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() { if (!sMutex) { - sMutex = new LLMutex(0); + sMutex = new LLMutex(); } } diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index d4af2c6b01..8f33d789eb 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -738,7 +738,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp) getSystemTime(&time_last); uuids_this_tick = uuids_per_tick; init = TRUE; - mMutex = new LLMutex(NULL); + mMutex = new LLMutex(); } uuid_time_t time_now = {0,0}; diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 4c197dc1d6..ca37fa14e4 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -37,7 +37,7 @@ LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded, bool should_pause) : LLQueuedThread(name, threaded, should_pause) { - mDeleteMutex = new LLMutex(NULL); + mDeleteMutex = new LLMutex(); if(!mLocalAPRFilePoolp) { @@ -204,7 +204,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na mWorkerClassName(name), mRequestHandle(LLWorkerThread::nullHandle()), mRequestPriority(LLWorkerThread::PRIORITY_NORMAL), - mMutex(NULL), mWorkFlags(0) { if (!mWorkerThread) diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp index 1829062af6..7c93c54cdf 100644 --- a/indra/llcorehttp/httpcommon.cpp +++ b/indra/llcorehttp/httpcommon.cpp @@ -333,7 +333,7 @@ LLMutex *getCurlMutex() if (!sHandleMutexp) { - sHandleMutexp = new LLMutex(NULL); + sHandleMutexp = new LLMutex(); } return sHandleMutexp; @@ -389,7 +389,7 @@ void initialize() S32 mutex_count = CRYPTO_num_locks(); for (S32 i = 0; i < mutex_count; i++) { - sSSLMutex.push_back(LLMutex_ptr(new LLMutex(NULL))); + sSSLMutex.push_back(LLMutex_ptr(new LLMutex())); } CRYPTO_set_id_callback(&ssl_thread_id); CRYPTO_set_locking_callback(&ssl_locking_callback); diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 4a76d15096..ab39ef46fa 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -595,7 +595,7 @@ void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_ { sUseNewByteRange = use_new_byte_range; sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent; - sMutex = new LLMutex(NULL); + sMutex = new LLMutex(); LLImageBase::createPrivatePool() ; } diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 4875fe7001..5f42fba866 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -35,7 +35,7 @@ LLImageDecodeThread::LLImageDecodeThread(bool threaded) : LLQueuedThread("imagedecode", threaded) { - mCreationMutex = new LLMutex(getAPRPool()); + mCreationMutex = new LLMutex(); } //virtual diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 3b8f08e0c6..0ae7123a6c 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -214,7 +214,7 @@ void LLVolumeMgr::useMutex() { if (!mDataMutex) { - mDataMutex = new LLMutex(gAPRPoolp); + mDataMutex = new LLMutex(); } } diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp index d07d9980c3..1a0eceba0f 100644 --- a/indra/llmessage/llbuffer.cpp +++ b/indra/llmessage/llbuffer.cpp @@ -265,7 +265,7 @@ void LLBufferArray::setThreaded(bool threaded) { if(!mMutexp) { - mMutexp = new LLMutex(NULL); + mMutexp = new LLMutex(); } } else diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index 537efa69d8..d164289c49 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -48,7 +48,6 @@ static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP LLProxy::LLProxy(): mHTTPProxyEnabled(false), - mProxyMutex(NULL), mUDPProxy(), mTCPProxy(), mHTTPProxy(), diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h index d2c5d37571..3166f80b5b 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -394,8 +394,8 @@ protected: S32 mCurrentPoolReallocCount; #if LL_THREADS_APR - apr_thread_mutex_t* mChainsMutex; - apr_thread_mutex_t* mCallbackMutex; + std::mutex* mChainsMutex; + std::mutex* mCallbackMutex; #else int* mChainsMutex; int* mCallbackMutex; diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp index 9468696507..b78e7d6f66 100644 --- a/indra/llplugin/llpluginmessagepipe.cpp +++ b/indra/llplugin/llpluginmessagepipe.cpp @@ -92,8 +92,6 @@ void LLPluginMessagePipeOwner::killMessagePipe(void) } LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): - mInputMutex(gAPRPoolp), - mOutputMutex(gAPRPoolp), mOutputStartIndex(0), mOwner(owner), mSocket(socket) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 0a8e58ac90..bcb944097c 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -79,12 +79,11 @@ protected: }; -LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): - mIncomingQueueMutex(gAPRPoolp) +LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) { if(!sInstancesMutex) { - sInstancesMutex = new LLMutex(gAPRPoolp); + sInstancesMutex = new LLMutex(); } mOwner = owner; diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp index db0eac7031..f60e8b832b 100644 --- a/indra/llvfs/llvfs.cpp +++ b/indra/llvfs/llvfs.cpp @@ -234,7 +234,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename mDataFP(NULL), mIndexFP(NULL) { - mDataMutex = new LLMutex(0); + mDataMutex = new LLMutex(); S32 i; for (i = 0; i < VFSLOCK_COUNT; i++) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 464e216cf0..eb550197b0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2152,7 +2152,7 @@ bool LLAppViewer::initThreads() if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog) { - LLTrace::BlockTimer::setLogLock(new LLMutex(NULL)); + LLTrace::BlockTimer::setLogLock(new LLMutex()); mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName); mFastTimerLogThread->start(); } diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index b48ecc8f31..6926068230 100644 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -46,7 +46,6 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")), mAccountName(session_id[LL_FCP_ACCOUNT_NAME]), mCompleteName(session_id[LL_FCP_COMPLETE_NAME]), - mMutex(NULL), mShowHistory(false), mMessages(NULL), mHistoryThreadsBusy(false), diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index da84a6b8f8..393b1a8225 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -258,7 +258,7 @@ mCalculateBtn(NULL) sInstance = this; mLastMouseX = 0; mLastMouseY = 0; - mStatusLock = new LLMutex(NULL); + mStatusLock = new LLMutex(); mModelPreview = NULL; mLODMode[LLModel::LOD_HIGH] = 0; @@ -1195,7 +1195,7 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl //----------------------------------------------------------------------------- LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) -: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL) +: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) , mLodsQuery() , mLodsWithParsingError() , mPelvisZOffset( 0.0f ) diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index c535fc1cdf..b1416521d2 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -516,7 +516,7 @@ LLMutex* LLLogChat::historyThreadsMutex() { if (sHistoryThreadsMutex == NULL) { - sHistoryThreadsMutex = new LLMutex(NULL); + sHistoryThreadsMutex = new LLMutex(); } return sHistoryThreadsMutex; } @@ -1012,8 +1012,6 @@ void LLDeleteHistoryThread::run() LLActionThread::LLActionThread(const std::string& name) : LLThread(name), - mMutex(NULL), - mRunCondition(NULL), mFinished(false) { } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index fdaa28b22b..2ba5592c15 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -809,9 +809,9 @@ LLMeshRepoThread::LLMeshRepoThread() { LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); - mMutex = new LLMutex(NULL); - mHeaderMutex = new LLMutex(NULL); - mSignal = new LLCondition(NULL); + mMutex = new LLMutex(); + mHeaderMutex = new LLMutex(); + mSignal = new LLCondition(); mHttpRequest = new LLCore::HttpRequest; mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions); mHttpOptions->setTransferTimeout(SMALL_MESH_XFER_TIMEOUT); @@ -1914,7 +1914,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mUploadSkin = upload_skin; mUploadJoints = upload_joints; mLockScaleIfJointPosition = lock_scale_if_joint_position; - mMutex = new LLMutex(NULL); + mMutex = new LLMutex(); mPendingUploads = 0; mFinished = false; mOrigin = gAgent.getPositionAgent(); @@ -3308,7 +3308,7 @@ LLMeshRepository::LLMeshRepository() void LLMeshRepository::init() { - mMeshMutex = new LLMutex(NULL); + mMeshMutex = new LLMutex(); LLConvexDecomposition::getInstance()->initSystem(); @@ -4189,8 +4189,8 @@ LLPhysicsDecomp::LLPhysicsDecomp() mQuitting = false; mDone = false; - mSignal = new LLCondition(NULL); - mMutex = new LLMutex(NULL); + mSignal = new LLCondition(); + mMutex = new LLMutex(); } LLPhysicsDecomp::~LLPhysicsDecomp() diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index dadf2f9701..327744e895 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -825,10 +825,6 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted) LLTextureCache::LLTextureCache(bool threaded) : LLWorkerThread("TextureCache", threaded), - mWorkersMutex(NULL), - mHeaderMutex(NULL), - mListMutex(NULL), - mFastCacheMutex(NULL), mHeaderAPRFile(NULL), mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called. mTexturesSizeTotal(0), diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 1f7796e6d0..3bf6e71ad4 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -925,7 +925,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mCanUseHTTP(true), mRetryAttempt(0), mActiveCount(0), - mWorkMutex(NULL), mFirstPacket(0), mLastPacket(-1), mTotalPackets(0), @@ -2543,8 +2542,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mDebugPause(FALSE), mPacketCount(0), mBadPacketCount(0), - mQueueMutex(getAPRPool()), - mNetworkQueueMutex(getAPRPool()), mTextureCache(cache), mImageDecodeThread(imagedecodethread), mTextureBandwidth(0), diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 90355b7166..bbec8d2282 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -157,7 +157,7 @@ void LLFilePickerThread::run() //static void LLFilePickerThread::initClass() { - sMutex = new LLMutex(NULL); + sMutex = new LLMutex(); } //static diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index 2782cd9545..5675653f02 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -185,7 +185,7 @@ void LLWatchdog::init(killer_event_callback func) mKillerCallback = func; if(!mSuspectsAccessMutex && !mTimer) { - mSuspectsAccessMutex = new LLMutex(NULL); + mSuspectsAccessMutex = new LLMutex(); mTimer = new LLWatchdogTimerThread(); mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000); mLastClockCount = LLTimer::getTotalTime(); From c272a37897b515ff8dcf42804020cee8bb199f07 Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 5 Apr 2018 15:11:20 +0200 Subject: [PATCH 03/10] Replace apr threads with std::thread. --- indra/llcommon/llthread.cpp | 65 ++++++++++++++++--------------------- indra/llcommon/llthread.h | 7 ++-- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 1e68124867..73c91a5210 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -116,29 +116,27 @@ void LLThread::registerThreadID() // // Handed to the APR thread creation function // -void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap) +void LLThread::staticRun() { - LLThread *threadp = (LLThread *)datap; - #ifdef LL_WINDOWS - set_thread_name(-1, threadp->mName.c_str()); + set_thread_name( -1, mName.c_str() ); #endif // for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread - threadp->mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder()); + mRecorder = new LLTrace::ThreadRecorder( *LLTrace::get_master_thread_recorder() ); - sThreadID = threadp->mID; + sThreadID = mID; // Run the user supplied function do { try { - threadp->run(); + run(); } catch (const LLContinueError &e) { - LL_WARNS("THREAD") << "ContinueException on thread '" << threadp->mName << + LL_WARNS( "THREAD" ) << "ContinueException on thread '" << mName << "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL; //output possible call stacks to log file. LLError::LLCallStacks::print(); @@ -154,24 +152,24 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // We're done with the run function, this thread is done executing now. //NB: we are using this flag to sync across threads...we really need memory barriers here - threadp->mStatus = STOPPED; + mStatus = STOPPED; - delete threadp->mRecorder; - threadp->mRecorder = NULL; + delete mRecorder; + mRecorder = nullptr; - return NULL; + return; } LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mPaused(FALSE), mName(name), - mAPRThreadp(NULL), + mThreadp(NULL), mStatus(STOPPED), mRecorder(NULL) { mID = ++sIDIter; - + // Thread creation probably CAN be paranoid about APR being initialized, if necessary if (poolp) { @@ -214,7 +212,7 @@ void LLThread::shutdown() // Warning! If you somehow call the thread destructor from itself, // the thread will die in an unclean fashion! - if (mAPRThreadp) + if( mThreadp ) { if (!isStopped()) { @@ -248,10 +246,12 @@ void LLThread::shutdown() // Put a stake in its heart. delete mRecorder; - apr_thread_exit(mAPRThreadp, -1); + // ND: There is no such thing as to terminate a std::thread, we detach it so no wait will happen. + // Otherwise craft something platform specific with std::thread::native_handle + mThreadp->detach(); return; } - mAPRThreadp = NULL; + mThreadp = NULL; } delete mRunCondition; @@ -283,21 +283,16 @@ void LLThread::start() // Set thread state to running mStatus = RUNNING; - apr_status_t status = - apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp); - - if(status == APR_SUCCESS) - { - // We won't bother joining - apr_thread_detach(mAPRThreadp); + try + { + mThreadp = new std::thread( std::bind( &LLThread::staticRun, this ) ); + //mThreadp->detach(); + } + catch( std::system_error& ex ) + { + mStatus = STOPPED; + LL_WARNS() << "failed to start thread " << mName << " " << ex.what() << LL_ENDL; } - else - { - mStatus = STOPPED; - LL_WARNS() << "failed to start thread " << mName << LL_ENDL; - ll_apr_warn_status(status); - } - } //============================================================================ @@ -372,11 +367,7 @@ U32 LLThread::currentID() // static void LLThread::yield() { -#if LL_LINUX || LL_SOLARIS - sched_yield(); // annoyingly, apr_thread_yield is a noop on linux... -#else - apr_thread_yield(); -#endif + std::this_thread::yield(); } void LLThread::wake() @@ -417,7 +408,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() void LLThreadSafeRefCount::cleanupThreadSafeRefCount() { delete sMutex; - sMutex = NULL; + sMutex = nullptr; } diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index dda7fa8ffb..c5a8c59852 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -34,6 +34,8 @@ #include "llmutex.h" #include "llrefcount.h" +#include + LL_COMMON_API void assert_main_thread(); namespace LLTrace @@ -99,15 +101,14 @@ public: private: BOOL mPaused; - // static function passed to APR thread creation routine - static void *APR_THREAD_FUNC staticRun(struct apr_thread_t *apr_threadp, void *datap); + void staticRun( ); protected: std::string mName; class LLCondition* mRunCondition; LLMutex* mDataLock; - apr_thread_t *mAPRThreadp; + std::thread *mThreadp; apr_pool_t *mAPRPoolp; BOOL mIsLocalPool; EThreadStatus mStatus; From d089e84d531e2cb87c20a8ee43c5a4529e048431 Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 5 Apr 2018 17:49:07 +0200 Subject: [PATCH 04/10] Remove now unused APR pool. --- indra/llcommon/llthread.cpp | 17 ----------------- indra/llcommon/llthread.h | 3 --- 2 files changed, 20 deletions(-) diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 73c91a5210..e1564339f7 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -170,17 +170,6 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mID = ++sIDIter; - // Thread creation probably CAN be paranoid about APR being initialized, if necessary - if (poolp) - { - mIsLocalPool = FALSE; - mAPRPoolp = poolp; - } - else - { - mIsLocalPool = TRUE; - apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread - } mRunCondition = new LLCondition(); mDataLock = new LLMutex(); mLocalAPRFilePoolp = NULL ; @@ -260,12 +249,6 @@ void LLThread::shutdown() delete mDataLock; mDataLock = NULL; - if (mIsLocalPool && mAPRPoolp) - { - apr_pool_destroy(mAPRPoolp); - mAPRPoolp = 0; - } - if (mRecorder) { // missed chance to properly shut down recorder (needs to be done in thread context) diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index c5a8c59852..9c24875db2 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -88,7 +88,6 @@ public: // this kicks off the apr thread void start(void); - apr_pool_t *getAPRPool() { return mAPRPoolp; } LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; } U32 getID() const { return mID; } @@ -109,8 +108,6 @@ protected: LLMutex* mDataLock; std::thread *mThreadp; - apr_pool_t *mAPRPoolp; - BOOL mIsLocalPool; EThreadStatus mStatus; U32 mID; LLTrace::ThreadRecorder* mRecorder; From ae363481346dc3fc4d81128246a58fb9c65b3111 Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 5 Apr 2018 17:50:36 +0200 Subject: [PATCH 05/10] Remove apr queue and replace it with a deque and LLMutex. --- indra/llcommon/llthreadsafequeue.cpp | 82 -------------------- indra/llcommon/llthreadsafequeue.h | 112 +++++++++++++-------------- indra/newview/llmainlooprepeater.cpp | 2 +- 3 files changed, 56 insertions(+), 140 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp index 491f920c0f..4fbbc5a5e1 100644 --- a/indra/llcommon/llthreadsafequeue.cpp +++ b/indra/llcommon/llthreadsafequeue.cpp @@ -24,87 +24,5 @@ */ #include "linden_common.h" -#include -#include #include "llthreadsafequeue.h" -#include "llexception.h" - - -// LLThreadSafeQueueImplementation -//----------------------------------------------------------------------------- - - -LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity): - mOwnsPool(pool == 0), - mPool(pool), - mQueue(0) -{ - if(mOwnsPool) { - apr_status_t status = apr_pool_create(&mPool, 0); - if(status != APR_SUCCESS) LLTHROW(LLThreadSafeQueueError("failed to allocate pool")); - } else { - ; // No op. - } - - apr_status_t status = apr_queue_create(&mQueue, capacity, mPool); - if(status != APR_SUCCESS) LLTHROW(LLThreadSafeQueueError("failed to allocate queue")); -} - - -LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation() -{ - if(mQueue != 0) { - if(apr_queue_size(mQueue) != 0) LL_WARNS() << - "terminating queue which still contains " << apr_queue_size(mQueue) << - " elements;" << "memory will be leaked" << LL_ENDL; - apr_queue_term(mQueue); - } - if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool); -} - - -void LLThreadSafeQueueImplementation::pushFront(void * element) -{ - apr_status_t status = apr_queue_push(mQueue, element); - - if(status == APR_EINTR) { - LLTHROW(LLThreadSafeQueueInterrupt()); - } else if(status != APR_SUCCESS) { - LLTHROW(LLThreadSafeQueueError("push failed")); - } else { - ; // Success. - } -} - - -bool LLThreadSafeQueueImplementation::tryPushFront(void * element){ - return apr_queue_trypush(mQueue, element) == APR_SUCCESS; -} - - -void * LLThreadSafeQueueImplementation::popBack(void) -{ - void * element; - apr_status_t status = apr_queue_pop(mQueue, &element); - - if(status == APR_EINTR) { - LLTHROW(LLThreadSafeQueueInterrupt()); - } else if(status != APR_SUCCESS) { - LLTHROW(LLThreadSafeQueueError("pop failed")); - } else { - return element; - } -} - - -bool LLThreadSafeQueueImplementation::tryPopBack(void *& element) -{ - return apr_queue_trypop(mQueue, &element) == APR_SUCCESS; -} - - -size_t LLThreadSafeQueueImplementation::size() -{ - return apr_queue_size(mQueue); -} diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 45289ef0b4..ca06eee110 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -28,12 +28,9 @@ #define LL_LLTHREADSAFEQUEUE_H #include "llexception.h" +#include "llmutex.h" #include - - -struct apr_pool_t; // From apr_pools.h -class LLThreadSafeQueueImplementation; // See below. - +#include // // A general queue exception. @@ -65,29 +62,6 @@ public: }; -struct apr_queue_t; // From apr_queue.h - - -// -// Implementation details. -// -class LL_COMMON_API LLThreadSafeQueueImplementation -{ -public: - LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity); - ~LLThreadSafeQueueImplementation(); - void pushFront(void * element); - bool tryPushFront(void * element); - void * popBack(void); - bool tryPopBack(void *& element); - size_t size(); - -private: - bool mOwnsPool; - apr_pool_t * mPool; - apr_queue_t * mQueue; -}; - // // Implements a thread safe FIFO. @@ -100,7 +74,7 @@ public: // If the pool is set to NULL one will be allocated and managed by this // queue. - LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024); + LLThreadSafeQueue( U32 capacity = 1024); // Add an element to the front of queue (will block if the queue has // reached capacity). @@ -128,7 +102,9 @@ public: size_t size(); private: - LLThreadSafeQueueImplementation mImplementation; + std::deque< ElementT > mStorage; + LLMutex mLock; + U32 mCapacity; // Really needed? }; @@ -138,8 +114,8 @@ private: template -LLThreadSafeQueue::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity): - mImplementation(pool, capacity) +LLThreadSafeQueue::LLThreadSafeQueue( U32 capacity): + mCapacity( capacity ) { ; // No op. } @@ -148,12 +124,17 @@ LLThreadSafeQueue::LLThreadSafeQueue(apr_pool_t * pool, unsigned int c template void LLThreadSafeQueue::pushFront(ElementT const & element) { - ElementT * elementCopy = new ElementT(element); - try { - mImplementation.pushFront(elementCopy); - } catch (LLThreadSafeQueueInterrupt) { - delete elementCopy; - throw; + while( true ) + { + { + LLMutexLock lck( &mLock ); + if( mStorage.size() < mCapacity ) + { + mStorage.push_front( element ); + return; + } + } + ms_sleep( 100 ); } } @@ -161,43 +142,60 @@ void LLThreadSafeQueue::pushFront(ElementT const & element) template bool LLThreadSafeQueue::tryPushFront(ElementT const & element) { - ElementT * elementCopy = new ElementT(element); - bool result = mImplementation.tryPushFront(elementCopy); - if(!result) delete elementCopy; - return result; + LLMutexTrylock lck( &mLock ); + if( !lck.isLocked() ) + return false; + + if( mStorage.size() >= mCapacity ) + return false; + + mStorage.push_front( element ); + return true; } template ElementT LLThreadSafeQueue::popBack(void) { - ElementT * element = reinterpret_cast (mImplementation.popBack()); - ElementT result(*element); - delete element; - return result; + while( true ) + { + { + LLMutexLock lck( &mLock ); + if( !mStorage.empty() ) + { + ElementT value = mStorage.back(); + mStorage.pop_back(); + return val; + } + } + ms_sleep( 100 ); + } } template bool LLThreadSafeQueue::tryPopBack(ElementT & element) { - void * storedElement; - bool result = mImplementation.tryPopBack(storedElement); - if(result) { - ElementT * elementPtr = reinterpret_cast(storedElement); - element = *elementPtr; - delete elementPtr; - } else { - ; // No op. - } - return result; + LLMutexTrylock lck( &mLock ); + + if( !lck.isLocked() ) + return false; + if( mStorage.empty() ) + return false; + + element = mStorage.back(); + mStorage.pop_back(); + return true; } template size_t LLThreadSafeQueue::size(void) { - return mImplementation.size(); + // Nicky: apr_queue_size is/was NOT threadsafe. I still play it safe here and rather lock the storage + + LLMutexLock lck( &mLock ); + return mStorage.size(); } diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp index db8d2e4ede..79bab4b077 100644 --- a/indra/newview/llmainlooprepeater.cpp +++ b/indra/newview/llmainlooprepeater.cpp @@ -46,7 +46,7 @@ void LLMainLoopRepeater::start(void) { if(mQueue != 0) return; - mQueue = new LLThreadSafeQueue(gAPRPoolp, 1024); + mQueue = new LLThreadSafeQueue( 1024); mMainLoopConnection = LLEventPumps::instance(). obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1)); mRepeaterConnection = LLEventPumps::instance(). From 1d79c7c1841609f65518a39b1336281b0f7acc0d Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 5 Apr 2018 20:24:35 +0200 Subject: [PATCH 06/10] Because GCC 4.8 has a libstc++ that is a special snowflake and does not define std::atomic_(u)int32_t --- indra/llcommon/llapp.h | 6 ++++++ indra/llcommon/llapr.h | 6 ++++++ indra/llcommon/llinstancetracker.h | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 60a4d19a00..5b32975c78 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -33,7 +33,13 @@ #include // Forward declarations template class LLAtomic; + +#ifndef LL_LINUX typedef LLAtomic LLAtomicU32; +#else +typedef LLAtomic LLAtomicU32; +#endif + class LLErrorThread; class LLLiveFile; #if LL_LINUX diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index d08014b5ef..3acaa8197e 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -198,8 +198,14 @@ private: AtomicType mData; }; +#ifndef LL_LINUX typedef LLAtomic LLAtomicU32; typedef LLAtomic LLAtomicS32; +#else +typedef LLAtomic LLAtomicU32; +typedef LLAtomic LLAtomicS32; +#endif + typedef LLAtomic LLAtomicBool; // File IO convenience functions. diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index c90dbfcabd..a66aa2fb63 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -82,7 +82,11 @@ protected: void decrementDepth(); U32 getDepth(); private: + #ifndef LL_LINUX std::atomic_uint32_t sIterationNestDepth; + #else + std::atomic_uint sIterationNestDepth; + #endif }; }; From 310122ff8bc2f1a0f2ec62e59fd893ede8f79df0 Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 5 Apr 2018 21:46:23 +0200 Subject: [PATCH 07/10] More changed for gcc. - Need to include lltimer.h for ms_sleep - Fix typo in LLThreadSafeQueue::popBack. visual Studio did not care as method never is instantiated. --- indra/llcommon/llthreadsafequeue.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index ca06eee110..01109b2b27 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -29,6 +29,7 @@ #include "llexception.h" #include "llmutex.h" +#include "lltimer.h" #include #include @@ -165,7 +166,7 @@ ElementT LLThreadSafeQueue::popBack(void) { ElementT value = mStorage.back(); mStorage.pop_back(); - return val; + return value; } } ms_sleep( 100 ); From 155a5e4cd4614641d1aa169aaeaae8ac7234f2aa Mon Sep 17 00:00:00 2001 From: Nicky Date: Fri, 6 Apr 2018 00:11:57 +0200 Subject: [PATCH 08/10] After input from Nat: - Rename LLAtomic to LLAtomicBase - LLAtomicBase has now only one required argument, the type to wrap. The other will be deduced as std::atomic< Type > if not supplied. - I did notice the forward declaration in llapp.h was not used, so away with it. --- indra/llcommon/llapp.h | 7 ------ indra/llcommon/llapr.h | 33 ++++++++++++++-------------- indra/llcommon/llinstancetracker.cpp | 2 +- indra/llcommon/llqueuedthread.h | 2 +- 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 5b32975c78..bd0e409696 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -32,13 +32,6 @@ #include "llsd.h" #include // Forward declarations -template class LLAtomic; - -#ifndef LL_LINUX -typedef LLAtomic LLAtomicU32; -#else -typedef LLAtomic LLAtomicU32; -#endif class LLErrorThread; class LLLiveFile; diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 3acaa8197e..9ca47f6d66 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -174,39 +174,40 @@ protected: std::mutex* mMutex; }; -template class LLAtomic +template > class LLAtomicBase { public: - LLAtomic() {}; - LLAtomic( Type x ) { mData.store( x ); }; - ~LLAtomic() {}; + LLAtomicBase() {}; + LLAtomicBase( Type x ) { mData.store( x ); }; + ~LLAtomicBase() {}; - operator const Type() { return (Type)mData.load(); } + operator const Type() { return mData; } - Type CurrentValue() const { return (Type)mData; } + Type CurrentValue() const { return mData; } - Type operator =( Type x) { mData.store( x ); return Type(mData); } + Type operator =( Type x) { mData.store( x ); return mData; } void operator -=(Type x) { mData -= x; } void operator +=(Type x) { mData += x; } - Type operator ++(int) { return ++mData; } // Type++ - Type operator --(int) { return --mData; } // approximately --Type (0 if final is 0, non-zero otherwise) + Type operator ++(int) { return mData++; } + Type operator --(int) { return mData--; } - Type operator ++() { return mData++; } // Type++ - Type operator --() { return mData--; } // approximately --Type (0 if final is 0, non-zero otherwise) + Type operator ++() { return ++mData; } + Type operator --() { return --mData; } private: AtomicType mData; }; +// ND: Typedefs for specialized versions. Using std::atomic_(u)int32_t to get the optimzed implementation. #ifndef LL_LINUX -typedef LLAtomic LLAtomicU32; -typedef LLAtomic LLAtomicS32; +typedef LLAtomicBase LLAtomicU32; +typedef LLAtomicBase LLAtomicS32; #else -typedef LLAtomic LLAtomicU32; -typedef LLAtomic LLAtomicS32; +typedef LLAtomicBase LLAtomicU32; +typedef LLAtomicBase LLAtomicS32; #endif -typedef LLAtomic LLAtomicBool; +typedef LLAtomicBase LLAtomicBool; // File IO convenience functions. // Returns NULL if the file fails to open, sets *sizep to file size if not NULL diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp index 6352cac99c..3f990f4869 100644 --- a/indra/llcommon/llinstancetracker.cpp +++ b/indra/llcommon/llinstancetracker.cpp @@ -47,5 +47,5 @@ void LLInstanceTrackerBase::StaticBase::decrementDepth() U32 LLInstanceTrackerBase::StaticBase::getDepth() { - return sIterationNestDepth.load(); + return sIterationNestDepth; } diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index e97fb36b7b..3235265e69 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -128,7 +128,7 @@ public: }; protected: - LLAtomic > mStatus; + LLAtomicBase mStatus; U32 mPriority; U32 mFlags; }; From 3ea9a014232bc51eac4c5257e8502f8e633abd77 Mon Sep 17 00:00:00 2001 From: Nicky Date: Fri, 6 Apr 2018 09:49:32 +0200 Subject: [PATCH 09/10] Change pointer to member where possible and do a bit of cleanup in lerror (move the mutexex in there and us the LLMutextTryLock rather than a custom class). --- indra/llcommon/llapr.cpp | 13 ------ indra/llcommon/llapr.h | 3 -- indra/llcommon/llerror.cpp | 70 +++++----------------------- indra/llcommon/llmutex.cpp | 35 ++++---------- indra/llcommon/llmutex.h | 24 ++++++++-- indra/llcommon/llthread.cpp | 4 +- indra/llcommon/llthread.h | 6 +-- indra/llplugin/slplugin/slplugin.cpp | 1 - 8 files changed, 48 insertions(+), 108 deletions(-) diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 33c3d5db20..ec2d322885 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -33,8 +33,6 @@ apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool. -std::mutex *gLogMutexp = nullptr; -std::mutex *gCallStacksLogMutexp = nullptr; const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool @@ -46,17 +44,10 @@ void ll_init_apr() apr_initialize(); if (!gAPRPoolp) - { apr_pool_create(&gAPRPoolp, NULL); - - gLogMutexp = new std::mutex(); - gCallStacksLogMutexp = new std::mutex(); - } if(!LLAPRFile::sAPRFilePoolp) - { LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; - } LLThreadLocalPointerBase::initAllThreadLocalStorage(); gAPRInitialized = true; @@ -76,10 +67,6 @@ void ll_cleanup_apr() // Clean up the logging mutex // All other threads NEED to be done before we clean up APR, so this is okay. - delete gLogMutexp; - gLogMutexp = nullptr; - delete gCallStacksLogMutexp; - gCallStacksLogMutexp = nullptr; LLThreadLocalPointerBase::destroyAllThreadLocalStorage(); diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 9ca47f6d66..cafa771c22 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -53,9 +53,6 @@ #include "llstring.h" -extern LL_COMMON_API std::mutex* gLogMutexp; -extern std::mutex* gCallStacksLogMutexp; - struct apr_dso_handle_t; /** * @brief Function which appropriately logs error or remains quiet on diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index fdea42d08a..2367b5702b 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -52,6 +52,9 @@ #include "lltimer.h" namespace { + LLMutex gLogMutex; + LLMutex gCallStacksLogMutex ; + #if LL_WINDOWS void debugger_print(const std::string& s) { @@ -412,7 +415,7 @@ namespace namespace LLError { - class SettingsConfig : public LLRefCount + class SettingsConfig: public LLRefCount { friend class Settings; @@ -994,63 +997,14 @@ namespace { } return found_level; } - - class LogLock - { - public: - LogLock(); - ~LogLock(); - bool ok() const { return mOK; } - private: - bool mLocked; - bool mOK; - }; - - LogLock::LogLock() - : mLocked(false), mOK(false) - { - if (!gLogMutexp) - { - mOK = true; - return; - } - - const int MAX_RETRIES = 5; - for (int attempts = 0; attempts < MAX_RETRIES; ++attempts) - { - if( gLogMutexp->try_lock() ) - { - mLocked = true; - mOK = true; - return; - } - - ms_sleep(1); - //apr_thread_yield(); - // Just yielding won't necessarily work, I had problems with - // this on Linux - doug 12/02/04 - } - - // We're hosed, we can't get the mutex. Blah. - std::cerr << "LogLock::LogLock: failed to get mutex for log" - << std::endl; - } - - LogLock::~LogLock() - { - if (mLocked) - { - gLogMutexp->unlock(); - } - } } namespace LLError { bool Log::shouldLog(CallSite& site) { - LogLock lock; - if (!lock.ok()) + LLMutexTrylock lock( &gLogMutex,5); + if (!lock.isLocked() ) { return false; } @@ -1100,11 +1054,11 @@ namespace LLError std::ostringstream* Log::out() { - LogLock lock; + LLMutexTrylock lock(&gLogMutex,5); // If we hit a logging request very late during shutdown processing, // when either of the relevant LLSingletons has already been deleted, // DO NOT resurrect them. - if (lock.ok() && ! (Settings::wasDeleted() || Globals::wasDeleted())) + if (lock.isLocked() && ! (Settings::wasDeleted() || Globals::wasDeleted())) { Globals* g = Globals::getInstance(); @@ -1120,8 +1074,8 @@ namespace LLError void Log::flush(std::ostringstream* out, char* message) { - LogLock lock; - if (!lock.ok()) + LLMutexTrylock lock(&gLogMutex,5); + if (!lock.isLocked()) { return; } @@ -1160,8 +1114,8 @@ namespace LLError void Log::flush(std::ostringstream* out, const CallSite& site) { - LogLock lock; - if (!lock.ok()) + LLMutexTrylock lock(&gLogMutex,5); + if (!lock.isLocked()) { return; } diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index 1090acd9fd..7457204aa3 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -36,8 +36,6 @@ LLMutex::LLMutex() : mCount(0), mLockingThread(NO_THREAD) { - - mMutexp = new std::mutex(); } @@ -47,8 +45,6 @@ LLMutex::~LLMutex() //bad assertion, the subclass LLSignal might be "locked", and that's OK //llassert_always(!isLocked()); // better not be locked! #endif - delete mMutexp; - mMutexp = nullptr; } @@ -60,7 +56,7 @@ void LLMutex::lock() return; } - mMutexp->lock(); + mMutex.lock(); #if MUTEX_DEBUG // Have to have the lock before we can access the debug info @@ -90,18 +86,16 @@ void LLMutex::unlock() #endif mLockingThread = NO_THREAD; - mMutexp->unlock(); + mMutex.unlock(); } bool LLMutex::isLocked() { - if (!mMutexp->try_lock()) - { + if (!mMutex.try_lock()) return true; - } else { - mMutexp->unlock(); + mMutex.unlock(); return false; } } @@ -124,11 +118,9 @@ bool LLMutex::trylock() return true; } - if (!mMutexp->try_lock()) - { + if (!mMutex.try_lock()) return false; - } - + #if MUTEX_DEBUG // Have to have the lock before we can access the debug info U32 id = LLThread::currentID(); @@ -144,34 +136,27 @@ bool LLMutex::trylock() //============================================================================ LLCondition::LLCondition() - { - // base class (LLMutex) has already ensured that mAPRPoolp is set up. - mCondp = new std::condition_variable(); } - LLCondition::~LLCondition() { - delete mCondp; - mCondp = nullptr; } - void LLCondition::wait() { - std::unique_lock< std::mutex > lock( *mMutexp ); - mCondp->wait( lock ); + std::unique_lock< std::mutex > lock( mMutex ); + mCond.wait( lock ); } void LLCondition::signal() { - mCondp->notify_one() ; + mCond.notify_one() ; } void LLCondition::broadcast() { - mCondp->notify_all(); + mCond.notify_all(); } diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index 566f37c66a..0cdf33e62f 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -28,6 +28,7 @@ #define LL_LLMUTEX_H #include "stdtypes.h" +#include "lltimer.h" #if LL_WINDOWS #pragma warning(disable:4265) @@ -67,11 +68,11 @@ public: U32 lockingThread() const; //get ID of locking thread protected: - std::mutex *mMutexp; + std::mutex mMutex; mutable U32 mCount; mutable U32 mLockingThread; - BOOL mIsLocalPool; + bool mIsLocalPool; #if MUTEX_DEBUG std::map mIsLocked; @@ -90,7 +91,7 @@ public: void broadcast(); protected: - std::condition_variable* mCondp; + std::condition_variable mCond; }; class LLMutexLock @@ -132,6 +133,23 @@ public: if (mMutex) mLocked = mMutex->trylock(); } + LLMutexTrylock( LLMutex* mutex, U32 aTries ) + : mMutex( mutex ), + mLocked( false ) + { + if( !mMutex ) + return; + + U32 i = 0; + while( i < aTries ) + { + mLocked = mMutex->trylock(); + if( mLocked ) + break; + ++i; + ms_sleep( 10 ); + } + } ~LLMutexTrylock() { diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index e1564339f7..7cb745855e 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -116,7 +116,7 @@ void LLThread::registerThreadID() // // Handed to the APR thread creation function // -void LLThread::staticRun() +void LLThread::threadRun() { #ifdef LL_WINDOWS set_thread_name( -1, mName.c_str() ); @@ -268,7 +268,7 @@ void LLThread::start() try { - mThreadp = new std::thread( std::bind( &LLThread::staticRun, this ) ); + mThreadp = new std::thread( std::bind( &LLThread::threadRun, this ) ); //mThreadp->detach(); } catch( std::system_error& ex ) diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 9c24875db2..818b53e4a4 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -98,16 +98,16 @@ public: static void registerThreadID(); private: - BOOL mPaused; + bool mPaused; - void staticRun( ); + void threadRun( ); protected: std::string mName; class LLCondition* mRunCondition; LLMutex* mDataLock; - std::thread *mThreadp; + std::thread *mThreadp; EThreadStatus mStatus; U32 mID; LLTrace::ThreadRecorder* mRecorder; diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp index 5c54705c71..38a6e1d468 100644 --- a/indra/llplugin/slplugin/slplugin.cpp +++ b/indra/llplugin/slplugin/slplugin.cpp @@ -155,7 +155,6 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL int main(int argc, char **argv) #endif { - ll_init_apr(); // Set up llerror logging From d122ff8d435f960fec9de4d247adeba418c677c3 Mon Sep 17 00:00:00 2001 From: Nicky Date: Sun, 8 Apr 2018 18:26:48 +0200 Subject: [PATCH 10/10] Use LLCondition rather than LLMutex. Then we can conveniently .wait() in popBack rather then having to use a poll loop./ --- indra/llcommon/llthreadsafequeue.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 01109b2b27..c59a29e3b4 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -104,7 +104,7 @@ public: private: std::deque< ElementT > mStorage; - LLMutex mLock; + LLCondition mLock;; U32 mCapacity; // Really needed? }; @@ -132,6 +132,7 @@ void LLThreadSafeQueue::pushFront(ElementT const & element) if( mStorage.size() < mCapacity ) { mStorage.push_front( element ); + mLock.signal(); return; } } @@ -151,6 +152,7 @@ bool LLThreadSafeQueue::tryPushFront(ElementT const & element) return false; mStorage.push_front( element ); + mLock.signal(); return true; } @@ -160,16 +162,13 @@ ElementT LLThreadSafeQueue::popBack(void) { while( true ) { + mLock.wait(); + if( !mStorage.empty() ) { - LLMutexLock lck( &mLock ); - if( !mStorage.empty() ) - { - ElementT value = mStorage.back(); - mStorage.pop_back(); - return value; - } + ElementT value = mStorage.back(); + mStorage.pop_back(); + return value; } - ms_sleep( 100 ); } }