17 #ifndef _COMMON_UTIL_THREAD_POOL_H_
18 #define _COMMON_UTIL_THREAD_POOL_H_
23 #include <type_traits>
36 std::condition_variable v;
38 std::deque<std::packaged_task<void()>> work;
40 std::vector<std::future<void>> finished;
46 template <
class F,
class... Args>
auto enqueue(F&& f, Args&&... args) -> std::future<
typename std::result_of<F(Args...)>::type> {
47 using return_type =
typename std::result_of<F(Args...)>::type;
50 std::packaged_task<return_type()> p(std::forward<F>(f));
51 auto r = p.get_future();
53 std::unique_lock<std::mutex> l(m);
54 work.emplace_back(std::move(p));
60 void start(std::size_t N = 1) {
61 for(std::size_t i = 0; i < N; ++i) {
63 finished.push_back(std::async(std::launch::async, [
this] { thread_task(); }));
73 void cancel_pending() {
74 std::unique_lock<std::mutex> l(m);
80 std::unique_lock<std::mutex> l(m);
81 for(
auto&& unused : finished) {
93 std::packaged_task<void()> f;
95 std::unique_lock<std::mutex> l(m);
97 v.wait(l, [&] {
return !work.empty(); });
99 f = std::move(work.front());