diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 651808e5f7..493e5ab626 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -152,6 +152,7 @@ + diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters index c7ceb7adcb..62abbcc886 100644 --- a/Source/Core/Common/Common.vcxproj.filters +++ b/Source/Core/Common/Common.vcxproj.filters @@ -68,6 +68,7 @@ + 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 +#include +#include + +#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 +class WorkQueueThread +{ +public: + WorkQueueThread() = default; + WorkQueueThread(std::function function) { Reset(std::move(function)); } + ~WorkQueueThread() { Shutdown(); } + void Reset(std::function function) + { + Shutdown(); + m_shutdown.Clear(); + m_function = std::move(function); + m_thread = std::thread([this] { ThreadLoop(); }); + } + + template + void EmplaceItem(Args&&... args) + { + { + std::unique_lock 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 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 m_function; + std::thread m_thread; + Common::Event m_wakeup; + Common::Flag m_shutdown; + std::mutex m_lock; + std::queue m_items; +}; + +} // namespace Common