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