From 481713000b4b45f2ce6d397aa3326520bbb9da16 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 22 Feb 2018 15:23:14 +0200
Subject: [PATCH] MAINT-8183 Fixed some exit issues and crashes

---
 indra/llcommon/llthread.cpp        |  9 ++++++---
 indra/llvfs/lllfsthread.cpp        |  4 +++-
 indra/newview/llappviewer.cpp      | 27 +++++++++++++++++++++------
 indra/newview/llmeshrepository.cpp | 12 ++++++++++++
 4 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 32e8ea96828..1f4aa9b3a63 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -152,13 +152,16 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 
     //LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
 
-    // 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;
 
     delete threadp->mRecorder;
     threadp->mRecorder = NULL;
 
+    // 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
+    // Todo: add LLMutex per thread instead of flag?
+    // We are using "while (mStatus != STOPPED) {ms_sleep();}" everywhere.
+    threadp->mStatus = STOPPED;
+
     return NULL;
 }
 
diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp
index 2fd2614cce9..be8e83a56f0 100644
--- a/indra/llvfs/lllfsthread.cpp
+++ b/indra/llvfs/lllfsthread.cpp
@@ -52,13 +52,14 @@ S32 LLLFSThread::updateClass(U32 ms_elapsed)
 //static
 void LLLFSThread::cleanupClass()
 {
+	llassert(sLocal != NULL);
 	sLocal->setQuitting();
 	while (sLocal->getPending())
 	{
 		sLocal->update(0);
 	}
 	delete sLocal;
-	sLocal = 0;
+	sLocal = NULL;
 }
 
 //----------------------------------------------------------------------------
@@ -75,6 +76,7 @@ LLLFSThread::LLLFSThread(bool threaded) :
 
 LLLFSThread::~LLLFSThread()
 {
+	// mLocalAPRFilePoolp cleanup in LLThread
 	// ~LLQueuedThread() will be called here
 }
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index a0750214a82..85e94d57e8c 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1645,7 +1645,10 @@ bool LLAppViewer::cleanup()
 	LLEventPumps::instance().reset();
 
 	//dump scene loading monitor results
-	LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+	if (LLSceneMonitor::instanceExists())
+	{
+		LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+	}
 
 	// There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block
 	// here, completely redundant with the one that occurs later in this same
@@ -1687,8 +1690,11 @@ bool LLAppViewer::cleanup()
     // Give any remaining SLPlugin instances a chance to exit cleanly.
     LLPluginProcessParent::shutdown();
 
-	LLVoiceClient::getInstance()->terminate();
-	
+	if (LLVoiceClient::instanceExists())
+	{
+		LLVoiceClient::getInstance()->terminate();
+	}
+
 	disconnectViewer();
 
 	LL_INFOS() << "Viewer disconnected" << LL_ENDL;
@@ -1743,7 +1749,10 @@ bool LLAppViewer::cleanup()
 
 	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted.
 
-	LLWorldMap::getInstance()->reset(); // release any images
+	if (LLWorldMap::instanceExists())
+	{
+		LLWorldMap::getInstance()->reset(); // release any images
+	}
 
 	LLCalc::cleanUp();
 
@@ -1916,10 +1925,16 @@ bool LLAppViewer::cleanup()
 	LLURLHistory::saveFile("url_history.xml");
 
 	// save mute list. gMuteList used to also be deleted here too.
-	LLMuteList::getInstance()->cache(gAgent.getID());
+	if (gAgent.isInitialized() && LLMuteList::instanceExists())
+	{
+		LLMuteList::getInstance()->cache(gAgent.getID());
+	}
 
 	//save call log list
-	LLConversationLog::instance().cache();
+	if (LLConversationLog::instanceExists())
+	{
+		LLConversationLog::instance().cache();
+	}
 
 	if (mPurgeOnExit)
 	{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 69e69b134ae..f1c2234677d 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -836,6 +836,12 @@ LLMeshRepoThread::~LLMeshRepoThread()
 	mHttpRequestSet.clear();
     mHttpHeaders.reset();
 
+    while (!mDecompositionQ.empty())
+    {
+        delete mDecompositionQ.front();
+        mDecompositionQ.pop_front();
+    }
+
     delete mHttpRequest;
 	mHttpRequest = NULL;
 	delete mMutex;
@@ -1941,6 +1947,9 @@ LLMeshUploadThread::~LLMeshUploadThread()
 {
 	delete mHttpRequest;
 	mHttpRequest = NULL;
+	delete mMutex;
+	mMutex = NULL;
+
 }
 
 LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_model, LLMeshUploadThread* thread)
@@ -3321,6 +3330,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3
 
 LLMeshRepository::LLMeshRepository()
 : mMeshMutex(NULL),
+  mDecompThread(NULL),
   mMeshThreadCount(0),
   mThread(NULL)
 {
@@ -3350,6 +3360,8 @@ void LLMeshRepository::init()
 void LLMeshRepository::shutdown()
 {
 	LL_INFOS(LOG_MESH) << "Shutting down mesh repository." << LL_ENDL;
+	llassert(mThread != NULL);
+	llassert(mThread->mSignal != NULL);
 
 	metrics_teleport_started_signal.disconnect();
 
-- 
GitLab