diff options
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/llthread.h | 26 | ||||
| -rw-r--r-- | indra/llcommon/threadpool.cpp | 12 |
2 files changed, 37 insertions, 1 deletions
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index b97d479abc..38a5f4669f 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -33,6 +33,32 @@ extern void set_thread_name(const char* threadName); +// Join unless this is the calling thread. Joining the current thread throws +// system_error(resource_deadlock_would_occur) and aborts via std::terminate. +inline void ll_join_thread(std::thread& thread) +{ + if (!thread.joinable()) + { + return; + } + if (thread.get_id() == std::this_thread::get_id()) + { + thread.detach(); + return; + } + try + { + thread.join(); + } + catch (const std::system_error&) + { + if (thread.joinable()) + { + thread.detach(); + } + } +} + namespace LLTrace { class ThreadRecorder; diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index 6adbdffba8..668c8ba598 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -20,6 +20,7 @@ #include "commoncontrol.h" #include "llerror.h" #include "llevents.h" +#include "llthread.h" #include "llsd.h" #include "stringize.h" @@ -127,8 +128,17 @@ void LL::ThreadPoolBase::close() { if (pair.second.joinable()) { + // close() runs on a worker when the LLApp status listener + // fires on that thread. Joining it throws and aborts shutdown. + if (pair.second.get_id() == std::this_thread::get_id()) + { + LL_WARNS("ThreadPool") << mName << " detaching current thread " + << pair.first << LL_ENDL; + pair.second.detach(); + continue; + } LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL; - pair.second.join(); + ll_join_thread(pair.second); } } LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL; |
