From e6025de0d03749c9d89c33da76aa8952ab6119d1 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Tue, 31 Jan 2023 15:04:17 -0500 Subject: [PATCH] Small overhaul of LLThread for better shutdown behavior --- indra/llcommon/llthread.cpp | 43 ++++++++++++++---------------- indra/llcommon/llthread.h | 15 +++++------ indra/newview/llmeshrepository.cpp | 10 +++---- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 6aa6dc8335c..5934961b79a 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -124,19 +124,18 @@ LL_COMMON_API void assert_main_thread() } // -// Handed to the APR thread creation function +// Handed to the thread creation function // void LLThread::threadRun() { + // Set thread state to running + mStatus = RUNNING; + #ifdef LL_WINDOWS set_thread_name(mName.c_str()); #endif - LL_PROFILER_SET_THREAD_NAME( mName.c_str() ); - // this is the first point at which we're actually running in the new thread - mID = currentID(); - #ifndef LL_RELEASE_FOR_DOWNLOAD // for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder()); @@ -182,14 +181,13 @@ void LLThread::threadRun() LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mPaused(FALSE), mName(name), - mThreadp(NULL), mStatus(STOPPED) #ifndef LL_RELEASE_FOR_DOWNLOAD , mRecorder(NULL) #endif { - mRunCondition = new LLCondition(); - mDataLock = new LLMutex(); + mRunCondition = std::make_unique<LLCondition>(); + mDataLock = std::make_unique<LLMutex>(); mLocalAPRFilePoolp = NULL ; } @@ -251,16 +249,11 @@ void LLThread::shutdown() mThreadp->join(); LL_INFOS() << "Successfully joined thread: " << mName << LL_ENDL; } - - delete mThreadp; - mThreadp = NULL; } - delete mRunCondition; - mRunCondition = NULL; - - delete mDataLock; - mDataLock = NULL; + mThreadp.reset(); + mRunCondition.reset(); + mDataLock.reset(); #ifndef LL_RELEASE_FOR_DOWNLOAD if (mRecorder) { @@ -272,24 +265,28 @@ void LLThread::shutdown() #endif } - void LLThread::start() { llassert(isStopped()); - - // Set thread state to running - mStatus = RUNNING; - try { - mThreadp = new std::thread(std::bind(&LLThread::threadRun, this)); - mNativeHandle = mThreadp->native_handle(); + mThreadp = std::make_unique<std::thread>(std::bind(&LLThread::threadRun, this)); } catch (const std::system_error& err) { mStatus = CRASHED; LL_WARNS() << "Failed to start thread: \"" << mName << "\" due to error: " << err.what() << LL_ENDL; } + catch (const std::bad_alloc& err) + { + mStatus = CRASHED; + LL_WARNS() << "Failed to allocate thread: \"" << mName << "\" due to error: " << err.what() << LL_ENDL; + } +} + +LLThread::id_t LLThread::getID() const +{ + return mThreadp ? mThreadp->get_id() : std::thread::id(); } //============================================================================ diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index c0856548fa9..99d03708de2 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -83,23 +83,20 @@ class LL_COMMON_API LLThread LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; } - id_t getID() const { return mID; } + id_t getID() const; private: bool mPaused; - std::thread::native_handle_type mNativeHandle; // for termination in case of issues - + // static function passed to APR thread creation routine void threadRun(); protected: std::string mName; - class LLCondition* mRunCondition; - LLMutex* mDataLock; - - std::thread *mThreadp; - EThreadStatus mStatus; - id_t mID; + std::unique_ptr<class LLCondition> mRunCondition; + std::unique_ptr<LLMutex> mDataLock; + std::unique_ptr<std::thread> mThreadp; + std::atomic_int mStatus; #ifndef LL_RELEASE_FOR_DOWNLOAD LLTrace::ThreadRecorder* mRecorder; #endif diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 3d9db3dc538..b04a255c50f 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1411,7 +1411,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) LLCore::HttpHandle handle = getByteRange(http_url, legacy_cap_version, info.mOffset, info.mSize, handler); if (LLCORE_HTTP_HANDLE_INVALID == handle) { - LL_WARNS(LOG_MESH) << "HTTP GET request failed for skin info on mesh " << mID + LL_WARNS(LOG_MESH) << "HTTP GET request failed for skin info on mesh " << getID() << ". Reason: " << mHttpStatus.toString() << " (" << mHttpStatus.toTerseString() << ")" << LL_ENDL; @@ -1469,7 +1469,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) LLCore::HttpHandle handle = getByteRange(http_url, legacy_cap_version, info.mOffset, info.mSize, handler); if (LLCORE_HTTP_HANDLE_INVALID == handle) { - LL_WARNS(LOG_MESH) << "HTTP GET request failed for decomposition mesh " << mID + LL_WARNS(LOG_MESH) << "HTTP GET request failed for decomposition mesh " << getID() << ". Reason: " << mHttpStatus.toString() << " (" << mHttpStatus.toTerseString() << ")" << LL_ENDL; @@ -1511,7 +1511,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) LLCore::HttpHandle handle = getByteRange(http_url, legacy_cap_version, info.mOffset, info.mSize, handler); if (LLCORE_HTTP_HANDLE_INVALID == handle) { - LL_WARNS(LOG_MESH) << "HTTP GET request failed for physics shape on mesh " << mID + LL_WARNS(LOG_MESH) << "HTTP GET request failed for physics shape on mesh " << getID() << ". Reason: " << mHttpStatus.toString() << " (" << mHttpStatus.toTerseString() << ")" << LL_ENDL; @@ -1613,7 +1613,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c LLCore::HttpHandle handle = getByteRange(http_url, legacy_cap_version, 0, MESH_HEADER_SIZE, handler); if (LLCORE_HTTP_HANDLE_INVALID == handle) { - LL_WARNS(LOG_MESH) << "HTTP GET request failed for mesh header " << mID + LL_WARNS(LOG_MESH) << "HTTP GET request failed for mesh header " << getID() << ". Reason: " << mHttpStatus.toString() << " (" << mHttpStatus.toTerseString() << ")" << LL_ENDL; @@ -1661,7 +1661,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, LLCore::HttpHandle handle = getByteRange(http_url, legacy_cap_version, info.mOffset, info.mSize, handler); if (LLCORE_HTTP_HANDLE_INVALID == handle) { - LL_WARNS(LOG_MESH) << "HTTP GET request failed for LOD on mesh " << mID + LL_WARNS(LOG_MESH) << "HTTP GET request failed for LOD on mesh " << getID() << ". Reason: " << mHttpStatus.toString() << " (" << mHttpStatus.toTerseString() << ")" << LL_ENDL; -- GitLab