12 #ifndef HIPIPE_CORE_THREAD_HPP
13 #define HIPIPE_CORE_THREAD_HPP
15 #include <boost/asio.hpp>
16 #include <boost/thread/thread.hpp>
21 #include <experimental/optional>
33 boost::asio::io_service service_;
34 std::experimental::optional<boost::asio::io_service::work> work_{service_};
35 boost::thread_group threads_;
42 thread_pool(
unsigned n_threads = std::thread::hardware_concurrency())
45 n_threads = std::max(1u, n_threads);
47 for (
unsigned i = 0; i < n_threads; ++i) {
48 threads_.create_thread([
this]() {
return this->service_.run(); });
66 template<
typename Fun,
typename... Args>
67 std::future<std::result_of_t<Fun(Args...)>>
enqueue(Fun fun, Args... args)
69 using Ret = std::result_of_t<Fun(Args...)>;
70 std::packaged_task<Ret(Args...)> task{fun};
71 std::future<Ret> future = task.get_future();
75 auto shared_task = std::make_shared<std::packaged_task<Ret(Args...)>>(std::move(task));
76 auto shared_args = std::make_shared<std::tuple<Args...>>(std::move(args)...);
77 auto asio_task = [task = std::move(shared_task), args = std::move(shared_args)]() {
78 return std::apply(std::move(*task), std::move(*args));
80 service_.post(std::move(asio_task));
89 work_ = std::experimental::nullopt;