Common: Add AsyncWorkThread.

This commit is contained in:
Jordan Woyak
2025-04-29 20:33:39 -05:00
parent 0066119e41
commit be4b0af971

View File

@ -5,6 +5,7 @@
#include <atomic>
#include <functional>
#include <future>
#include <mutex>
#include <string>
#include <thread>
@ -13,8 +14,6 @@
#include "Common/SPSCQueue.h"
#include "Common/Thread.h"
// A thread that executes the given function for every item placed into its queue.
namespace Common
{
namespace detail
@ -158,6 +157,38 @@ private:
using ProducerMutex = std::conditional_t<IsSingleProducer, DummyMutex, std::recursive_mutex>;
ProducerMutex m_mutex;
};
// A WorkQueueThread-like class that takes functions to invoke.
template <template <typename> typename WorkThread>
class AsyncWorkThreadBase
{
public:
using FuncType = std::function<void()>;
AsyncWorkThreadBase() = default;
explicit AsyncWorkThreadBase(std::string thread_name) { Reset(std::move(thread_name)); }
void Reset(std::string thread_name)
{
m_worker.Reset(std::move(thread_name), std::invoke<FuncType>);
}
void Push(FuncType func) { m_worker.Push(std::move(func)); }
auto PushBlocking(FuncType func)
{
std::packaged_task task{std::move(func)};
m_worker.EmplaceItem([&] { task(); });
return task.get_future().get();
}
void Cancel() { m_worker.Cancel(); }
void Shutdown() { m_worker.Shutdown(); }
void WaitForCompletion() { m_worker.WaitForCompletion(); }
private:
WorkThread<FuncType> m_worker;
};
} // namespace detail
// Multiple threads may use the public interface.
@ -169,4 +200,7 @@ using WorkQueueThread = detail::WorkQueueThreadBase<T, false>;
template <typename T>
using WorkQueueThreadSP = detail::WorkQueueThreadBase<T, true>;
using AsyncWorkThread = detail::AsyncWorkThreadBase<WorkQueueThread>;
using AsyncWorkThreadSP = detail::AsyncWorkThreadBase<WorkQueueThreadSP>;
} // namespace Common