From d94117b80b67b6d27d2b2e14fb420682474e439e Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 9 Feb 2011 20:06:46 -0600
Subject: [PATCH] SH-920 Wait for threads to shut down before deleting them --
 also, fix some assertions that were encouraging people to comment out the
 destruction of LLSignal.

---
 indra/llcommon/llthread.cpp        |  5 +++
 indra/newview/llmeshrepository.cpp | 49 ++++++++++++++++++++++++------
 2 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index b4617c54534..d9400fb5b32 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -425,6 +425,11 @@ 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);
 }
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index edcf249a217..a2b0ac09af2 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -470,7 +470,12 @@ LLMeshRepoThread::LLMeshRepoThread()
 
 LLMeshRepoThread::~LLMeshRepoThread()
 {
-	
+	delete mMutex;
+	mMutex = NULL;
+	delete mHeaderMutex;
+	mHeaderMutex = NULL;
+	delete mSignal;
+	mSignal = NULL;
 }
 
 void LLMeshRepoThread::run()
@@ -573,6 +578,11 @@ void LLMeshRepoThread::run()
 		}
 	}
 	
+	if (mSignal->isLocked())
+	{ //make sure to let go of the mutex associated with the given signal before shutting down
+		mSignal->unlock();
+	}
+
 	res = LLConvexDecomposition::quitThread();
 	if (res != LLCD_OK)
 	{
@@ -580,7 +590,7 @@ void LLMeshRepoThread::run()
 	}
 
 	delete mCurlRequest;
-	delete mMutex;
+	mCurlRequest = NULL;
 }
 
 void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id)
@@ -2115,13 +2125,24 @@ void LLMeshRepository::init()
 
 void LLMeshRepository::shutdown()
 {
-	mThread->mSignal->signal();
+	llinfos << "Shutting down mesh repository." << llendl;
 
+	mThread->mSignal->signal();
+	
+	while (!mThread->isStopped())
+	{
+		apr_sleep(10);
+	}
 	delete mThread;
 	mThread = NULL;
 
 	for (U32 i = 0; i < mUploads.size(); ++i)
 	{
+		llinfos << "Waiting for pending mesh upload " << i << "/" << mUploads.size() << llendl;
+		while (!mUploads[i]->isStopped())
+		{
+			apr_sleep(10);
+		}
 		delete mUploads[i];
 	}
 
@@ -2130,9 +2151,11 @@ void LLMeshRepository::shutdown()
 	delete mMeshMutex;
 	mMeshMutex = NULL;
 
+	llinfos << "Shutting down decomposition system." << llendl;
+
 	if (mDecompThread)
 	{
-		mDecompThread->shutdown();
+		mDecompThread->shutdown();		
 		delete mDecompThread;
 		mDecompThread = NULL;
 	}
@@ -3130,6 +3153,11 @@ LLPhysicsDecomp::LLPhysicsDecomp()
 LLPhysicsDecomp::~LLPhysicsDecomp()
 {
 	shutdown();
+
+	delete mSignal;
+	mSignal = NULL;
+	delete mMutex;
+	mMutex = NULL;
 }
 
 void LLPhysicsDecomp::shutdown()
@@ -3139,9 +3167,9 @@ void LLPhysicsDecomp::shutdown()
 		mQuitting = true;
 		mSignal->signal();
 
-		while (!mDone)
+		while (!isStopped())
 		{
-			apr_sleep(100);
+			apr_sleep(10);
 		}
 	}
 }
@@ -3519,10 +3547,11 @@ void LLPhysicsDecomp::run()
 
 	decomp->quitThread();
 	
-	//delete mSignal;
-	delete mMutex;
-	mSignal = NULL;
-	mMutex = NULL;
+	if (mSignal->isLocked())
+	{ //let go of mSignal's associated mutex
+		mSignal->unlock();
+	}
+
 	mDone = true;
 }
 
-- 
GitLab