diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2024-05-29 09:49:56 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2024-05-29 09:49:56 -0400 |
commit | 316bc0bdf30514a0c6894ef7c2859e79bf02a546 (patch) | |
tree | e829a65510be02498f806d9c0c4861097f30f9f6 /indra/llcommon | |
parent | 30da8853c88e755ac5c0836f3952d16d501d3502 (diff) |
Make ~ThreadPool() join every thread before destroying its vector.
Otherwise we fall into the trap of destroying a joinable std::thread, which
calls std::terminate() and hence our crash-on-terminate() handler.
The previous ~ThreadPool() logic only joined threads if the queue wasn't
already closed, but evidently we can reach the destructor with the queue
closed but the threads not yet joined.
Fixes #1534.
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/threadpool.cpp | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index edccdb097b..0f445b84fb 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -109,20 +109,19 @@ LL::ThreadPoolBase::~ThreadPoolBase() void LL::ThreadPoolBase::close() { - if (! mQueue->isClosed()) + // mQueue might have been closed already, but in any case we must join or + // detach each of our threads before destroying the mThreads vector. + LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL; + mQueue->close(); + for (auto& pair: mThreads) { - LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL; - mQueue->close(); - for (auto& pair: mThreads) + if (pair.second.joinable()) { - if (pair.second.joinable()) - { - LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL; - pair.second.join(); - } + LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL; + pair.second.join(); } - LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL; } + LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL; } void LL::ThreadPoolBase::run(const std::string& name) |