diff options
author | Euclid Linden <euclid@lindenlab.com> | 2022-05-27 21:15:49 +0000 |
---|---|---|
committer | Euclid Linden <euclid@lindenlab.com> | 2022-05-27 21:15:49 +0000 |
commit | 3f98411c56f4daa06c9102346a8dd37af18d2cb6 (patch) | |
tree | 4255c2827cc3e07921275bfd7937f4f43f29d5fa /indra/llcommon/threadpool.cpp | |
parent | 3f58ec2fdfb76ce2160884a3e97be49f60b6ac90 (diff) | |
parent | 02c71b0ac2f99dd1c26a649ffce2182b2fc9a7d9 (diff) |
Merged in DV528-merge-6.6.1 (pull request #1000)
DRTVWR-528 merge up to 6.6.1
Diffstat (limited to 'indra/llcommon/threadpool.cpp')
-rw-r--r-- | indra/llcommon/threadpool.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp new file mode 100644 index 0000000000..ba914035e2 --- /dev/null +++ b/indra/llcommon/threadpool.cpp @@ -0,0 +1,88 @@ +/** + * @file threadpool.cpp + * @author Nat Goodspeed + * @date 2021-10-21 + * @brief Implementation for threadpool. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "threadpool.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" +#include "llevents.h" +#include "stringize.h" + +LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity): + mQueue(name, capacity), + mName("ThreadPool:" + name), + mThreadCount(threads) +{} + +void LL::ThreadPool::start() +{ + for (size_t i = 0; i < mThreadCount; ++i) + { + std::string tname{ stringize(mName, ':', (i+1), '/', mThreadCount) }; + mThreads.emplace_back(tname, [this, tname]() + { + LL_PROFILER_SET_THREAD_NAME(tname.c_str()); + run(tname); + }); + } + // Listen on "LLApp", and when the app is shutting down, close the queue + // and join the workers. + LLEventPumps::instance().obtain("LLApp").listen( + mName, + [this](const LLSD& stat) + { + std::string status(stat["status"]); + if (status != "running") + { + // viewer is starting shutdown -- proclaim the end is nigh! + LL_DEBUGS("ThreadPool") << mName << " saw " << status << LL_ENDL; + close(); + } + return false; + }); +} + +LL::ThreadPool::~ThreadPool() +{ + close(); +} + +void LL::ThreadPool::close() +{ + if (! mQueue.isClosed()) + { + LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL; + mQueue.close(); + for (auto& pair: mThreads) + { + LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL; + pair.second.join(); + } + LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL; + } +} + +void LL::ThreadPool::run(const std::string& name) +{ + LL_DEBUGS("ThreadPool") << name << " starting" << LL_ENDL; + run(); + LL_DEBUGS("ThreadPool") << name << " stopping" << LL_ENDL; +} + +void LL::ThreadPool::run() +{ + mQueue.runUntilClose(); +} |