2 * @file CpuTaskExecutor.tpp
3 * @brief Template implementation for CpuTaskExecutor - async CPU-bound task execution with timeout support
12 #include "CpuTaskExecutor.h"
20 * @brief Execute CPU-bound task asynchronously without timeout
21 * @tparam Func Function type (auto-deduced)
22 * @param resultLooper SLLooper instance for result callback execution
23 * @param func CPU-intensive function to execute in separate thread
24 * @return Promise<ReturnType> Promise for result retrieval and continuation chaining
26 * Executes CPU-intensive tasks in a separate thread to avoid blocking the main
27 * event loop. The function is executed asynchronously using std::async with
28 * std::launch::async policy to guarantee separate thread execution. Results
29 * are delivered back to the specified event loop thread for thread-safe
32 * Key implementation details:
33 * - **Separate thread**: Uses std::async with std::launch::async for guaranteed thread
34 * - **Thread-safe results**: Results posted back to specified SLLooper thread
35 * - **Exception safety**: Automatic exception capture and propagation
36 * - **Void support**: Template specialization handles void-returning functions
37 * - **Move semantics**: Efficient parameter and result transfer
38 * - **Fire-and-forget**: std::future is stored but not waited on (Promise coordination)
41 * 1. Create promise for result coordination
42 * 2. Launch async task in separate thread
43 * 3. Execute function and capture result/exception
44 * 4. Post result back to event loop thread via SLLooper
45 * 5. Resolve promise in event loop thread context
48 * auto promise = CpuTaskExecutor::executeAsync(looper, []() {
49 * // CPU-intensive computation
50 * return fibonacci(45); // This runs in separate thread
53 * promise.then(looper, [](long result) {
54 * // This callback runs in event loop thread
55 * std::cout << "Fibonacci result: " << result << std::endl;
56 * }).catch_error(looper, [](std::exception_ptr ex) {
57 * std::cerr << "Computation failed!" << std::endl;
61 * @note Function executes in separate thread - ensure thread safety
62 * @note Result callbacks execute in specified SLLooper thread context
63 * @note std::future is intentionally not waited on - Promise provides coordination
64 * @warning Avoid capturing SLLooper or other event loop objects in func
66 * @see \ref swt::CpuTaskExecutor "CpuTaskExecutor", \ref swt::Promise "Promise", \ref swt::SLLooper "SLLooper"
68 template<typename Func>
69 auto CpuTaskExecutor::executeAsync(std::shared_ptr<SLLooper> resultLooper,
71 -> Promise<decltype(func())> {
73 using ReturnType = decltype(func());
74 auto promise = resultLooper->createPromise<ReturnType>();
76 // Launch async task - std::future stored to prevent immediate destruction
77 // but not waited on since Promise provides coordination mechanism
78 auto asyncFuture = std::async(std::launch::async, [promise, func = std::forward<Func>(func), resultLooper]() mutable {
80 if constexpr (std::is_void_v<ReturnType>) {
81 // Handle void-returning function
83 // Post success result back to event loop thread
84 resultLooper->post([promise]() mutable {
88 // Handle value-returning function
90 // Post result back to event loop thread with move semantics
91 resultLooper->post([promise, result = std::move(result)]() mutable {
92 promise.set_value(std::move(result));
96 // Capture any exception thrown during execution
97 auto exception = std::current_exception();
98 // Post exception back to event loop thread
99 resultLooper->post([promise, exception]() mutable {
100 promise.set_exception(exception);
105 // Suppress unused variable warning - future is intentionally not waited on
106 // Promise mechanism provides the coordination, not std::future
113 * @brief Execute CPU-bound task asynchronously with timeout protection
114 * @tparam Func Function type (auto-deduced)
115 * @param resultLooper SLLooper instance for result callback execution
116 * @param func CPU-intensive function to execute in separate thread
117 * @param timeout Maximum execution time before task is considered failed
118 * @return Promise<ReturnType> Promise for result retrieval and continuation chaining
120 * Executes CPU-intensive tasks with timeout protection to prevent runaway
121 * computations from hanging the application. Uses a two-level async approach:
122 * an outer async task manages timeout detection, while an inner async task
123 * executes the actual function. If the function doesn't complete within the
124 * timeout, a CpuTaskTimeoutException is generated.
126 * Key implementation Details:
127 * - **Timeout protection**: std::future::wait_for with timeout detection
128 * - **Two-level async**: Outer timeout management, inner task execution
129 * - **Exception types**: CpuTaskTimeoutException for timeout vs function exceptions
130 * - **Resource cleanup**: Timeout tasks are abandoned but system handles cleanup
131 * - **Thread safety**: Same result posting mechanism as non-timeout version
134 * - **Within timeout**: Normal result/exception delivery via Promise
135 * - **Timeout exceeded**: CpuTaskTimeoutException delivered via Promise
136 * - **Background cleanup**: System handles cleanup of abandoned timeout tasks
139 * auto promise = CpuTaskExecutor::executeAsync(looper, []() {
140 * return longRunningComputation(); // May take a long time
141 * }, 5000ms); // 5 second timeout
143 * promise.then(looper, [](auto result) {
144 * std::cout << "Completed in time: " << result << std::endl;
145 * }).catch_error(looper, [](std::exception_ptr ex) {
147 * std::rethrow_exception(ex);
148 * } catch (const CpuTaskTimeoutException& timeout) {
149 * std::cerr << "Task timed out: " << timeout.what() << std::endl;
150 * } catch (const std::exception& other) {
151 * std::cerr << "Task failed: " << other.what() << std::endl;
156 * @note Timeout detection uses std::future::wait_for for precision
157 * @note Timed-out tasks continue running but results are discarded
158 * @note CpuTaskTimeoutException provides timeout duration information
159 * @warning Long-running tasks may continue executing after timeout
161 * @see \ref swt::CpuTaskTimeoutException "CpuTaskTimeoutException", \ref swt::Promise "Promise", \ref swt::SLLooper "SLLooper"
163 template<typename Func>
164 auto CpuTaskExecutor::executeAsync(std::shared_ptr<SLLooper> resultLooper,
166 std::chrono::milliseconds timeout)
167 -> Promise<decltype(func())> {
169 using ReturnType = decltype(func());
170 auto promise = resultLooper->createPromise<ReturnType>();
172 // Launch timeout management task
173 auto asyncFuture = std::async(std::launch::async, [promise, func = std::forward<Func>(func), resultLooper, timeout]() mutable {
175 // Launch inner task for actual function execution
176 auto taskFuture = std::async(std::launch::async, std::move(func));
178 // Wait for completion or timeout
179 if (taskFuture.wait_for(timeout) == std::future_status::timeout) {
180 // Timeout occurred - create timeout exception
181 auto timeoutException = std::make_exception_ptr(
182 CpuTaskTimeoutException("CPU task timeout after " +
183 std::to_string(timeout.count()) + "ms"));
184 // Post timeout exception back to event loop thread
185 resultLooper->post([promise, timeoutException]() mutable {
186 promise.set_exception(timeoutException);
188 return; // Exit timeout management task
191 // Task completed within timeout - retrieve result
192 if constexpr (std::is_void_v<ReturnType>) {
193 // Handle void-returning function
194 taskFuture.get(); // May throw if function threw
195 // Post success result back to event loop thread
196 resultLooper->post([promise]() mutable {
200 // Handle value-returning function
201 auto result = taskFuture.get(); // May throw if function threw
202 // Post result back to event loop thread
203 resultLooper->post([promise, result = std::move(result)]() mutable {
204 promise.set_value(std::move(result));
209 // Capture any exception (from taskFuture.get() or other operations)
210 auto exception = std::current_exception();
211 // Post exception back to event loop thread
212 resultLooper->post([promise, exception]() mutable {
213 promise.set_exception(exception);
218 // Suppress unused variable warning - future provides timeout management
219 // but Promise provides the primary coordination mechanism