diff options
Diffstat (limited to 'indra/llcommon/threadpool.cpp')
-rw-r--r-- | indra/llcommon/threadpool.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp new file mode 100644 index 0000000000..aa7d4179a2 --- /dev/null +++ b/indra/llcommon/threadpool.cpp @@ -0,0 +1,75 @@ +/** + * @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): + mQueue(name), + mName("ThreadPool:" + name) +{ + for (size_t i = 0; i < threads; ++i) + { + std::string tname{ STRINGIZE(mName << ':' << (i+i) << '/' << threads) }; + mThreads.emplace_back(tname, [this, tname](){ 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; + mQueue.runUntilClose(); + LL_DEBUGS("ThreadPool") << name << " stopping" << LL_ENDL; +} |