From e4a8ef4ce2572db98d08233c58e23d3ec75f30d7 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 22 Jul 2011 02:33:55 -0500
Subject: [PATCH] SH-2031 Cleanup from threaded curl implementation (remove
 errors/loops on shutdown).

---
 indra/llcommon/llthread.cpp |  3 ++-
 indra/llmessage/llcurl.cpp  | 38 ++++++++++++++++++++++++++-----------
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index d9400fb5b32..4063cc730b4 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -323,7 +323,8 @@ LLMutex::LLMutex(apr_pool_t *poolp) :
 LLMutex::~LLMutex()
 {
 #if MUTEX_DEBUG
-	llassert_always(!isLocked()); // better not be locked!
+	//bad assertion, the subclass LLSignal might be "locked", and that's OK
+	//llassert_always(!isLocked()); // better not be locked!
 #endif
 	apr_thread_mutex_destroy(mAPRMutexp);
 	mAPRMutexp = NULL;
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 2bb36f494c8..1e735c4bbd7 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -693,21 +693,25 @@ void LLCurl::Multi::run()
 	while (!mQuitting)
 	{
 		mSignal->wait();
-		S32 q = 0;
-		for (S32 call_count = 0;
-			 call_count < MULTI_PERFORM_CALL_REPEAT;
-			 call_count += 1)
+
+		if (!mQuitting)
 		{
-			CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
-			if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
+			S32 q = 0;
+			for (S32 call_count = 0;
+				 call_count < MULTI_PERFORM_CALL_REPEAT;
+				 call_count += 1)
 			{
-				check_curl_multi_code(code);
-				break;
-			}
+				CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
+				if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
+				{
+					check_curl_multi_code(code);
+					break;
+				}
 	
+			}
+			mQueued = q;
+			mPerformState = PERFORM_STATE_COMPLETED;
 		}
-		mQueued = q;
-		mPerformState = PERFORM_STATE_COMPLETED;
 	}
 }
 
@@ -830,6 +834,18 @@ LLCurlRequest::LLCurlRequest() :
 LLCurlRequest::~LLCurlRequest()
 {
 	llassert_always(mThreadID == LLThread::currentID());
+
+	//stop all Multi handle background threads
+	for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter)
+	{
+		LLCurl::Multi* multi = *iter;
+		multi->mQuitting = true;
+		while (!multi->isStopped())
+		{
+			multi->mSignal->signal();
+			apr_sleep(1000);
+		}
+	}
 	for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer());
 }
 
-- 
GitLab