From 7a09a5391ac5172470eb6597f08b24cd5965e9ac Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 3 Dec 2019 11:33:55 -0500 Subject: DRTVWR-494: Add on_main_thread(), sibling to assert_main_thread(). --- indra/llcommon/llthread.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index a4171729db..f875e4e0dc 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -97,14 +97,34 @@ U32 LL_THREAD_LOCAL sThreadID = 0; U32 LLThread::sIDIter = 0; +namespace +{ + + U32 main_thread() + { + // Using a function-static variable to identify the main thread + // requires that control reach here from the main thread before it + // reaches here from any other thread. We simply trust that whichever + // thread gets here first is the main thread. + static U32 s_thread_id = LLThread::currentID(); + return s_thread_id; + } + +} // anonymous namespace + +LL_COMMON_API bool on_main_thread() +{ + return (LLThread::currentID() == main_thread()); +} LL_COMMON_API void assert_main_thread() { - static U32 s_thread_id = LLThread::currentID(); - if (LLThread::currentID() != s_thread_id) + auto curr = LLThread::currentID(); + auto main = main_thread(); + if (curr != main) { - LL_WARNS() << "Illegal execution from thread id " << (S32) LLThread::currentID() - << " outside main thread " << (S32) s_thread_id << LL_ENDL; + LL_WARNS() << "Illegal execution from thread id " << curr + << " outside main thread " << main << LL_ENDL; } } -- cgit v1.2.3 From 5e7df752a66b2082d063d2c4a10bc7013d479f55 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 6 Dec 2019 16:31:49 -0500 Subject: DRTVWR-494: Use std::thread::id for LLThread::currentID(). LLThread::currentID() used to return a U32, a distinct unsigned value incremented by explicitly constructing LLThread or by calling LLThread:: registerThreadID() early in a thread launched by other means. The latter imposed an unobvious requirement on new code based on std::thread. Using std::thread::id instead delegates to the compiler/library the problem of distinguishing threads launched by any means. Change lots of explicit U32 declarations. Introduce LLThread::id_t typedef to avoid having to run around fixing uses again if we later revisit this decision. LLMutex, which stores an LLThread::id_t, wants a distinguished value meaning NO_THREAD, and had an enum with that name. But as std::thread::id promises that the default-constructed value is distinct from every valid value, NO_THREAD becomes unnecessary and goes away. Because LLMutex now stores LLThread::id_t instead of U32, make llmutex.h #include "llthread.h" instead of the other way around. This makes LLMutex an incomplete type within llthread.h, so move LLThread::lockData() and unlockData() to the .cpp file. Similarly, remove llrefcount.h's #include "llmutex.h" to break circularity; instead forward-declare LLMutex. It turns out that a number of source files assumed that #include "llthread.h" would get the definition for LLMutex. Sprinkle #include "llmutex.h" as needed. In the SAFE_SSL code in llcorehttp/httpcommon.cpp, there's an ssl_thread_id() callback that returns an unsigned long to the SSL library. When LLThread:: currentID() was U32, we could simply return that. But std::thread::id is very deliberately opaque, and can't be reinterpret_cast to unsigned long. Fortunately it can be hashed because std::hash is specialized with that type. --- indra/llcommon/llthread.cpp | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index f875e4e0dc..0b9dec969c 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -92,21 +92,16 @@ void set_thread_name( DWORD dwThreadID, const char* threadName) // } // //---------------------------------------------------------------------------- - -U32 LL_THREAD_LOCAL sThreadID = 0; - -U32 LLThread::sIDIter = 0; - namespace { - U32 main_thread() + LLThread::id_t main_thread() { // Using a function-static variable to identify the main thread // requires that control reach here from the main thread before it // reaches here from any other thread. We simply trust that whichever // thread gets here first is the main thread. - static U32 s_thread_id = LLThread::currentID(); + static LLThread::id_t s_thread_id = LLThread::currentID(); return s_thread_id; } @@ -128,10 +123,8 @@ LL_COMMON_API void assert_main_thread() } } -void LLThread::registerThreadID() -{ - sThreadID = ++sIDIter; -} +// this function has become moot +void LLThread::registerThreadID() {} // // Handed to the APR thread creation function @@ -142,11 +135,12 @@ void LLThread::threadRun() set_thread_name(-1, mName.c_str()); #endif + // this is the first point at which we're actually running in the new thread + mID = currentID(); + // 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()); - sThreadID = mID; - // Run the user supplied function do { @@ -188,8 +182,6 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mStatus(STOPPED), mRecorder(NULL) { - - mID = ++sIDIter; mRunCondition = new LLCondition(); mDataLock = new LLMutex(); mLocalAPRFilePoolp = NULL ; @@ -367,9 +359,9 @@ void LLThread::setQuitting() } // static -U32 LLThread::currentID() +LLThread::id_t LLThread::currentID() { - return sThreadID; + return std::this_thread::get_id(); } // static @@ -396,6 +388,16 @@ void LLThread::wakeLocked() } } +void LLThread::lockData() +{ + mDataLock->lock(); +} + +void LLThread::unlockData() +{ + mDataLock->unlock(); +} + //============================================================================ //---------------------------------------------------------------------------- -- cgit v1.2.3