diff options
| author | Michael M <mchtly@gmail.com> | 2017-08-20 14:04:49 -0700 |
|---|---|---|
| committer | Michael M <mchtly@gmail.com> | 2017-08-20 14:40:56 -0700 |
| commit | de9378bf6389ad22ca955df477a48bd678c10c9e (patch) | |
| tree | c12f370737390b9d8159ecab2fe38739ee90e62d /Source/Core/Common/WorkQueueThread.h | |
| parent | 16d6ccbdf7bed6a1da122e0bcd0747d9bcbd650f (diff) | |
Common: add WorkQueueThread
Diffstat (limited to 'Source/Core/Common/WorkQueueThread.h')
| -rw-r--r-- | Source/Core/Common/WorkQueueThread.h | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/Source/Core/Common/WorkQueueThread.h b/Source/Core/Common/WorkQueueThread.h new file mode 100644 index 0000000000..8947b099cb --- /dev/null +++ b/Source/Core/Common/WorkQueueThread.h @@ -0,0 +1,86 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include <functional> +#include <queue> +#include <thread> + +#include "Common/Event.h" +#include "Common/Flag.h" + +// A thread that executes the given function for every item placed into its queue. + +namespace Common +{ +template <typename T> +class WorkQueueThread +{ +public: + WorkQueueThread() = default; + WorkQueueThread(std::function<void(T)> function) { Reset(std::move(function)); } + ~WorkQueueThread() { Shutdown(); } + void Reset(std::function<void(T)> function) + { + Shutdown(); + m_shutdown.Clear(); + m_function = std::move(function); + m_thread = std::thread([this] { ThreadLoop(); }); + } + + template <typename... Args> + void EmplaceItem(Args&&... args) + { + { + std::unique_lock<std::mutex> lg(m_lock); + m_items.emplace(std::move(args)...); + } + m_wakeup.Set(); + } + +private: + void Shutdown() + { + if (m_thread.joinable()) + { + m_shutdown.Set(); + m_wakeup.Set(); + m_thread.join(); + } + } + + void ThreadLoop() + { + while (true) + { + m_wakeup.Wait(); + + while (true) + { + T item; + { + std::unique_lock<std::mutex> lg(m_lock); + if (m_items.empty()) + break; + item = m_items.front(); + m_items.pop(); + } + m_function(std::move(item)); + } + + if (m_shutdown.IsSet()) + break; + } + } + + std::function<void(T)> m_function; + std::thread m_thread; + Common::Event m_wakeup; + Common::Flag m_shutdown; + std::mutex m_lock; + std::queue<T> m_items; +}; + +} // namespace Common |
