diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 1e68124867..73c91a5210 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -116,29 +116,27 @@ void LLThread::registerThreadID() // // Handed to the APR thread creation function // -void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap) +void LLThread::staticRun() { - LLThread *threadp = (LLThread *)datap; - #ifdef LL_WINDOWS - set_thread_name(-1, threadp->mName.c_str()); + set_thread_name( -1, mName.c_str() ); #endif // for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread - threadp->mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder()); + mRecorder = new LLTrace::ThreadRecorder( *LLTrace::get_master_thread_recorder() ); - sThreadID = threadp->mID; + sThreadID = mID; // Run the user supplied function do { try { - threadp->run(); + run(); } catch (const LLContinueError &e) { - LL_WARNS("THREAD") << "ContinueException on thread '" << threadp->mName << + LL_WARNS( "THREAD" ) << "ContinueException on thread '" << mName << "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL; //output possible call stacks to log file. LLError::LLCallStacks::print(); @@ -154,24 +152,24 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // 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; + mStatus = STOPPED; - delete threadp->mRecorder; - threadp->mRecorder = NULL; + delete mRecorder; + mRecorder = nullptr; - return NULL; + return; } LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mPaused(FALSE), mName(name), - mAPRThreadp(NULL), + mThreadp(NULL), mStatus(STOPPED), mRecorder(NULL) { mID = ++sIDIter; - + // Thread creation probably CAN be paranoid about APR being initialized, if necessary if (poolp) { @@ -214,7 +212,7 @@ void LLThread::shutdown() // Warning! If you somehow call the thread destructor from itself, // the thread will die in an unclean fashion! - if (mAPRThreadp) + if( mThreadp ) { if (!isStopped()) { @@ -248,10 +246,12 @@ void LLThread::shutdown() // Put a stake in its heart. delete mRecorder; - apr_thread_exit(mAPRThreadp, -1); + // ND: There is no such thing as to terminate a std::thread, we detach it so no wait will happen. + // Otherwise craft something platform specific with std::thread::native_handle + mThreadp->detach(); return; } - mAPRThreadp = NULL; + mThreadp = NULL; } delete mRunCondition; @@ -283,21 +283,16 @@ void LLThread::start() // Set thread state to running mStatus = RUNNING; - apr_status_t status = - apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp); - - if(status == APR_SUCCESS) - { - // We won't bother joining - apr_thread_detach(mAPRThreadp); + try + { + mThreadp = new std::thread( std::bind( &LLThread::staticRun, this ) ); + //mThreadp->detach(); + } + catch( std::system_error& ex ) + { + mStatus = STOPPED; + LL_WARNS() << "failed to start thread " << mName << " " << ex.what() << LL_ENDL; } - else - { - mStatus = STOPPED; - LL_WARNS() << "failed to start thread " << mName << LL_ENDL; - ll_apr_warn_status(status); - } - } //============================================================================ @@ -372,11 +367,7 @@ U32 LLThread::currentID() // static void LLThread::yield() { -#if LL_LINUX || LL_SOLARIS - sched_yield(); // annoyingly, apr_thread_yield is a noop on linux... -#else - apr_thread_yield(); -#endif + std::this_thread::yield(); } void LLThread::wake() @@ -417,7 +408,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() void LLThreadSafeRefCount::cleanupThreadSafeRefCount() { delete sMutex; - sMutex = NULL; + sMutex = nullptr; } diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index dda7fa8ffb..c5a8c59852 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -34,6 +34,8 @@ #include "llmutex.h" #include "llrefcount.h" +#include + LL_COMMON_API void assert_main_thread(); namespace LLTrace @@ -99,15 +101,14 @@ public: private: BOOL mPaused; - // static function passed to APR thread creation routine - static void *APR_THREAD_FUNC staticRun(struct apr_thread_t *apr_threadp, void *datap); + void staticRun( ); protected: std::string mName; class LLCondition* mRunCondition; LLMutex* mDataLock; - apr_thread_t *mAPRThreadp; + std::thread *mThreadp; apr_pool_t *mAPRPoolp; BOOL mIsLocalPool; EThreadStatus mStatus;