summaryrefslogtreecommitdiff
path: root/indra/llcommon/threadpool.cpp
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-05-29 09:49:56 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-05-29 09:49:56 -0400
commit316bc0bdf30514a0c6894ef7c2859e79bf02a546 (patch)
treee829a65510be02498f806d9c0c4861097f30f9f6 /indra/llcommon/threadpool.cpp
parent30da8853c88e755ac5c0836f3952d16d501d3502 (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/threadpool.cpp')
-rw-r--r--indra/llcommon/threadpool.cpp19
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)