From 86f07b4406decf72ef0f021734ed58902f854807 Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Tue, 21 Jul 2020 15:30:34 -0400
Subject: [PATCH] Some minor cleanup to threading, run threads as detached
 instead of leaving dangling and unjoined

---
 indra/llcommon/llthread.cpp         | 14 ++---
 indra/llcommon/lltimer.cpp          | 92 +++--------------------------
 indra/llprimitive/llmodelloader.cpp |  3 +-
 indra/newview/llmeshrepository.cpp  | 10 ++--
 4 files changed, 21 insertions(+), 98 deletions(-)

diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 0b9dec969ce..7f2955cec45 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -286,13 +286,13 @@ void LLThread::start()
     {
         mThreadp = new std::thread(std::bind(&LLThread::threadRun, this));
         mNativeHandle = mThreadp->native_handle();
-    }
-    catch (std::system_error& ex)
-    {
-        mStatus = STOPPED;
-        LL_WARNS() << "failed to start thread " << mName << " " << ex.what() << LL_ENDL;
-    }
-
+		mThreadp->detach();
+	}
+	catch (const std::system_error& err)
+	{
+		mStatus = CRASHED;
+		LL_WARNS() << "Failed to start thread: \"" << mName << "\" due to error: " << err.what() << LL_ENDL;
+	}
 }
 
 //============================================================================
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index f99636a0c58..6964a74e5c8 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -39,10 +39,15 @@
 #	error "architecture not supported"
 #endif
 
+#include <chrono>
+#include <thread>
+
 //
 // Locally used constants
 //
+#if LL_LINUX || LL_DARWIN || LL_SOLARIS
 const U64 SEC_TO_MICROSEC_U64 = 1000000;
+#endif
 
 //---------------------------------------------------------------------------
 // Globals and statics
@@ -61,101 +66,18 @@ LLTimer* LLTimer::sTimer = NULL;
 // Implementation
 //---------------------------------------------------------------------------
 
-#if LL_WINDOWS
 void ms_sleep(U32 ms)
 {
-	Sleep(ms);
+	std::this_thread::sleep_for(std::chrono::milliseconds(ms));
 }
 
 U32 micro_sleep(U64 us, U32 max_yields)
 {
     // max_yields is unused; just fiddle with it to avoid warnings.
     max_yields = 0;
-	ms_sleep((U32)(us / 1000));
+	std::this_thread::sleep_for(std::chrono::microseconds(us));
     return 0;
 }
-#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
-static void _sleep_loop(struct timespec& thiswait)
-{
-	struct timespec nextwait;
-	bool sleep_more = false;
-
-	do {
-		int result = nanosleep(&thiswait, &nextwait);
-
-		// check if sleep was interrupted by a signal; unslept
-		// remainder was written back into 't' and we just nanosleep
-		// again.
-		sleep_more = (result == -1 && EINTR == errno);
-
-		if (sleep_more)
-		{
-			if ( nextwait.tv_sec > thiswait.tv_sec ||
-			     (nextwait.tv_sec == thiswait.tv_sec &&
-			      nextwait.tv_nsec >= thiswait.tv_nsec) )
-			{
-				// if the remaining time isn't actually going
-				// down then we're being shafted by low clock
-				// resolution - manually massage the sleep time
-				// downward.
-				if (nextwait.tv_nsec > 1000000) {
-					// lose 1ms
-					nextwait.tv_nsec -= 1000000;
-				} else {
-					if (nextwait.tv_sec == 0) {
-						// already so close to finished
-						sleep_more = false;
-					} else {
-						// lose up to 1ms
-						nextwait.tv_nsec = 0;
-					}
-				}
-			}
-			thiswait = nextwait;
-		}
-	} while (sleep_more);
-}
-
-U32 micro_sleep(U64 us, U32 max_yields)
-{
-    U64 start = get_clock_count();
-    // This is kernel dependent.  Currently, our kernel generates software clock
-    // interrupts at 250 Hz (every 4,000 microseconds).
-    const U64 KERNEL_SLEEP_INTERVAL_US = 4000;
-
-    S32 num_sleep_intervals = (us - (KERNEL_SLEEP_INTERVAL_US >> 1)) / KERNEL_SLEEP_INTERVAL_US;
-    if (num_sleep_intervals > 0)
-    {
-        U64 sleep_time = (num_sleep_intervals * KERNEL_SLEEP_INTERVAL_US) - (KERNEL_SLEEP_INTERVAL_US >> 1);
-        struct timespec thiswait;
-        thiswait.tv_sec = sleep_time / 1000000;
-        thiswait.tv_nsec = (sleep_time % 1000000) * 1000l;
-        _sleep_loop(thiswait);
-    }
-
-    U64 current_clock = get_clock_count();
-    U32 yields = 0;
-    while (    (yields < max_yields)
-            && (current_clock - start < us) )
-    {
-        sched_yield();
-        ++yields;
-        current_clock = get_clock_count();
-    }
-    return yields;
-}
-
-void ms_sleep(U32 ms)
-{
-	long mslong = ms; // tv_nsec is a long
-	struct timespec thiswait;
-	thiswait.tv_sec = ms / 1000;
-	thiswait.tv_nsec = (mslong % 1000) * 1000000l;
-    _sleep_loop(thiswait);
-}
-#else
-# error "architecture not supported"
-#endif
 
 //
 // CPU clock/other clock frequency and count functions
diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp
index 4e468ff45f5..b0833c1e3d7 100644
--- a/indra/llprimitive/llmodelloader.cpp
+++ b/indra/llprimitive/llmodelloader.cpp
@@ -28,6 +28,7 @@
 #include "llsdserialize.h"
 #include "lljoint.h"
 #include "llcallbacklist.h"
+#include "lltimer.h"
 
 #include "glh/glh_linear.h"
 #include "llmatrix4a.h"
@@ -365,7 +366,7 @@ void LLModelLoader::loadModelCallback()
 
 	while (!isStopped())
 	{ //wait until this thread is stopped before deleting self
-		apr_sleep(100);
+		micro_sleep(100);
 	}
 
 	//double check if "this" is valid before deleting it, in case it is aborted during running.
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 98e0aa7dc1a..2c4ca3fc935 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2597,7 +2597,7 @@ void LLMeshUploadThread::generateHulls()
 		// on isDiscarded() prevents that.
 		while (! mPhysicsComplete && ! isDiscarded())
 		{
-			apr_sleep(100);
+			micro_sleep(100);
 		}
 	}	
 }
@@ -3531,7 +3531,7 @@ void LLMeshRepository::init()
 
 	while (!mDecompThread->mInited)
 	{ //wait for physics decomp thread to init
-		apr_sleep(100);
+		micro_sleep(100);
 	}
 
 	metrics_teleport_started_signal = LLViewerMessage::getInstance()->setTeleportStartedCallback(teleport_started);
@@ -3558,7 +3558,7 @@ void LLMeshRepository::shutdown()
 	
 	while (!mThread->isStopped())
 	{
-		apr_sleep(10);
+		micro_sleep(10);
 	}
 	delete mThread;
 	mThread = NULL;
@@ -3568,7 +3568,7 @@ void LLMeshRepository::shutdown()
 		LL_INFOS(LOG_MESH) << "Waiting for pending mesh upload " << (i + 1) << "/" << mUploads.size() << LL_ENDL;
 		while (!mUploads[i]->isStopped())
 		{
-			apr_sleep(10);
+			micro_sleep(10);
 		}
 		delete mUploads[i];
 	}
@@ -4722,7 +4722,7 @@ void LLPhysicsDecomp::shutdown()
 
 		while (!isStopped())
 		{
-			apr_sleep(10);
+			micro_sleep(10);
 		}
 	}
 }
-- 
GitLab