2** EPITECH PROJECT, 2025
5** ThreadPool.tpp, ThreadPool class implementation of enqueue method
11** Copyright (c) 2025 Robin Toillon
13** Permission is hereby granted, free of charge, to any person obtaining
14** a copy of this software and associated documentation files (the
15** "Software"), to deal in the Software without restriction, including
16** without limitation the rights to use, copy, modify, merge, publish,
17** distribute, sublicense, and/or sell copies of the Software, and to
18** permit persons to whom the Software is furnished to do so, subject to
19** the following conditions:
21** The above copyright notice and this permission notice shall be
22** included in all copies or substantial portions of the Software.
24** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 * @file ThreadPool.tpp
35 * @brief ThreadPool class template implementation
36 * @author Robin Toillon
37 * @details This file contains the implementation of the ThreadPool
38 * class template methods. Specifically, it implements the enqueue
39 * method which allows tasks to be added to the thread pool for
40 * asynchronous execution.
47 template<std::invocable F, typename... Args>
48 auto ThreadPool::enqueue(F &&f, Args &&...args)
49 -> std::expected<std::future<std::invoke_result_t<F, Args...>>,
52 using return_t = std::invoke_result_t<F, Args...>;
56 [func = std::forward<F>(f),
57 ...captured_args = std::forward<Args>(args)](void) mutable
60 return std::invoke(std::move(func),
61 std::move(captured_args)...);
64 std::packaged_task<return_t()> task(std::move(boundTask));
65 std::future<return_t> future = task.get_future();
67 std::unique_lock<std::mutex> lock(this->_queueMutex);
69 return std::unexpected{
70 Error::failure(ErrorCode::InternalRuntimeError,
71 "enqueue on stopped ThreadPool")};
72 this->_tasks.emplace([task = std::move(task)](void) mutable
75 this->_condition.notify_one();
78 } catch (const std::exception &e) {
79 return std::unexpected{
80 Error::failure(ErrorCode::InternalRuntimeError,
81 "Failed to enqueue task: {}", e.what())};
83 return std::unexpected{
84 Error::failure(ErrorCode::Unknown,
85 "Failed to enqueue task: Unknown error")};