-
Notifications
You must be signed in to change notification settings - Fork 0
/
ThreadPoolAsync.hpp
75 lines (55 loc) · 2.19 KB
/
ThreadPoolAsync.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
* vim:ts=4:shiftwidth=4:et:cindent:fileencoding=utf-8:
*/
#pragma once
#include <functional>
#include <condition_variable>
#include <cstdint>
#include <future>
#include "ThreadPool.hpp"
template <typename Func, typename ...Args>
concept bool VoidFunc = requires(Func aFunc, Args... aArgs)
{
{ aFunc(aArgs...) } -> void;
};
class ThreadPoolAsync final : public ThreadPool<std::future<void>>
{
public:
ThreadPoolAsync(const size_t aThrCnt, const bool aAffinity = false) : ThreadPool<std::future<void>>(aThrCnt, aAffinity)
{
}
ThreadPoolAsync(const ThreadPoolAsync&) = delete;
ThreadPoolAsync(ThreadPoolAsync&&) = delete;
ThreadPoolAsync& operator=(const ThreadPoolAsync&) = delete;
ThreadPoolAsync& operator=(ThreadPoolAsync&&) = delete;
void executeTask(std::optional<std::future<void>>&& aFuture) const override
{
aFuture.value().get();
}
template <typename Func, typename ...ArgType> requires VoidFunc<Func, ArgType...>
void push(Func&& aFunc, ArgType&&... aArgs)
{
auto sFuncWithArgs = std::bind(std::forward<Func>(aFunc), std::forward<ArgType>(aArgs)...);
auto sWrapper = [mFuncWithArgs{std::move(sFuncWithArgs)}] (void)
{
mFuncWithArgs();
};
mQueue.push(std::async(std::launch::deferred, std::move(sWrapper)));
mCond.notify_one();
}
template <typename Func, typename ...ArgType>
auto push(Func&& aFunc, ArgType&&... aArgs) -> std::future<decltype(aFunc(aArgs...))>
{
using RetType = decltype(aFunc(aArgs...));
std::promise<RetType> sPromise;
auto sFuture = sPromise.get_future();
auto sFuncWithArgs = std::bind(std::forward<Func>(aFunc), std::forward<ArgType>(aArgs)...);
auto sWrapper = [mFuncWithArgs{std::move(sFuncWithArgs)}, mPromise{std::move(sPromise)}] (void) mutable
{
mPromise.set_value(mFuncWithArgs());
};
mQueue.push(std::async(std::launch::deferred, std::move(sWrapper)));
mCond.notify_one();
return sFuture;
}
};