diff options
author | bunnei <bunneidev@gmail.com> | 2020-12-29 16:36:35 -0800 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2020-12-29 16:46:29 -0800 |
commit | 69e82d01d5012c0078f65a294ecbb7118707f73c (patch) | |
tree | d8bac45fa91904abec67a0d76c29e4f7e3aeaab8 /src/common/thread_worker.cpp | |
parent | c192da3f82ea3b2563ce43a340c88ac9a6602f26 (diff) |
common: ThreadWorker: Add class to help do asynchronous work.
Diffstat (limited to 'src/common/thread_worker.cpp')
-rw-r--r-- | src/common/thread_worker.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/common/thread_worker.cpp b/src/common/thread_worker.cpp new file mode 100644 index 0000000000..8f9bf447ae --- /dev/null +++ b/src/common/thread_worker.cpp @@ -0,0 +1,58 @@ +// Copyright 2020 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/thread.h" +#include "common/thread_worker.h" + +namespace Common { + +ThreadWorker::ThreadWorker(std::size_t num_workers, const std::string& name) { + for (std::size_t i = 0; i < num_workers; ++i) + threads.emplace_back([this, thread_name{std::string{name}}] { + Common::SetCurrentThreadName(thread_name.c_str()); + + // Wait for first request + { + std::unique_lock lock{queue_mutex}; + condition.wait(lock, [this] { return stop || !requests.empty(); }); + } + + while (true) { + std::function<void()> task; + + { + std::unique_lock lock{queue_mutex}; + condition.wait(lock, [this] { return stop || !requests.empty(); }); + if (stop || requests.empty()) { + return; + } + task = std::move(requests.front()); + requests.pop(); + } + + task(); + } + }); +} + +ThreadWorker::~ThreadWorker() { + { + std::unique_lock lock{queue_mutex}; + stop = true; + } + condition.notify_all(); + for (std::thread& thread : threads) { + thread.join(); + } +} + +void ThreadWorker::QueueWork(std::function<void()>&& work) { + { + std::unique_lock lock{queue_mutex}; + requests.emplace(work); + } + condition.notify_one(); +} + +} // namespace Common |