2#ifndef LIBSBX_ASSETS_THREAD_POOL_HPP_
3#define LIBSBX_ASSETS_THREAD_POOL_HPP_
7#include <condition_variable>
17#include <fmt/format.h>
19#include <libsbx/utility/logger.hpp>
21namespace sbx::assets {
27 thread_pool(
const std::size_t size = std::thread::hardware_concurrency())
29 _workers.reserve(size);
31 for ([[maybe_unused]]
auto i : std::views::iota(0u, size)) {
32 _workers.emplace_back([
this](){ _worker(); });
41 _condition.notify_all();
43 for (
auto& worker : _workers) {
51 template<
typename Function,
typename... Args>
52 requires (std::is_invocable_v<Function, Args...>)
53 auto submit(Function&& function, Args&&... args) -> std::future<std::invoke_result_t<Function, Args...>> {
54 using result_type = std::invoke_result_t<Function, Args...>;
56 auto promise = std::make_shared<std::promise<result_type>>();
57 auto future = promise->get_future();
60 auto lock = std::scoped_lock{_mutex};
62 _tasks.emplace([promise, function = std::forward<Function>(function), ...args = std::forward<Args>(args)](){
64 if constexpr (std::is_void_v<result_type>) {
65 std::invoke(function, std::forward<Args>(args)...);
68 promise->set_value(std::invoke(function, std::forward<Args>(args)...));
72 promise->set_exception(std::current_exception());
74 utility::logger<
"assets">::error(
"Failed to set exception for promise");
80 _condition.notify_one();
88 auto _worker() ->
void {
90 auto lock = std::unique_lock{_mutex};
92 _condition.wait(lock, [
this](){
return !_tasks.empty() || !_is_running; });
98 auto task = std::move(_tasks.front());
107 std::vector<std::thread> _workers;
108 std::queue<std::function<void()>> _tasks;
111 std::condition_variable _condition;
113 std::atomic_bool _is_running;
Definition: thread_pool.hpp:23
Definition: logger.hpp:124