ladivic
Loading...
Searching...
No Matches
ldvc_async.hpp
Go to the documentation of this file.
1/*
2 * This file is part of the ladivic library.
3 * Copyright (c) 2024 Nathanne Isip
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24/**
25 *
26 * @file ldvc_async.hpp
27 * @brief Provides utilities for asynchronous execution in C++.
28 *
29 * This header file defines functions for executing tasks asynchronously in C++,
30 * providing capabilities for delayed execution and timeout handling.
31 *
32 * @author Nathanne Isip
33 *
34 */
35
36#ifndef LDVC_ASYNC_HPP
37#define LDVC_ASYNC_HPP
38
39#include <future>
40
41/**
42 *
43 * @brief Executes a function asynchronously.
44 *
45 * This function executes the given function `f` asynchronously, along with its
46 * arguments `args`. It returns a std::future object representing the result
47 * of the function call.
48 *
49 * @tparam F The type of the function to be executed.
50 * @tparam A The types of the arguments to the function.
51 *
52 * @param f The function to be executed.
53 * @param args The arguments to the function.
54 *
55 * @return std::future<typename std::result_of<F(A...)>::type> A future object
56 * representing the result of the function call.
57 *
58 */
59template<typename F, typename... A>
60std::future<typename std::result_of<F(A...)>::type> ldvc_async_execute(F&& f, A&&... args)
61{
62 using return_type = typename std::result_of<F(A...)>::type;
63
64 std::packaged_task<return_type()> task(std::bind(std::forward<F>(f), std::forward<A>(args)...));
65 std::future<return_type> result = task.get_future();
66 std::thread(std::move(task)).detach();
67
68 return result;
69}
70
71/**
72 *
73 * @brief Executes a function asynchronously with a delay.
74 *
75 * This function executes the given function `f` asynchronously, along with its
76 * arguments `args`, after the specified delay. It returns a std::future object
77 * representing the result of the function call.
78 *
79 * @tparam R The type of the delay duration.
80 * @tparam P The type of the delay duration.
81 * @tparam F The type of the function to be executed.
82 * @tparam A The types of the arguments to the function.
83 *
84 * @param delay The delay duration before executing the function.
85 * @param f The function to be executed.
86 * @param args The arguments to the function.
87 *
88 * @return std::future<typename std::result_of<F(A...)>::type> A future object
89 * representing the result of the function call.
90 *
91 */
92template<typename R, typename P, typename F, typename... A>
93std::future<typename std::result_of<F(A...)>::type> ldvc_async_execute_with_delay(
94 const std::chrono::duration<R, P>& delay,
95 F&& f,
96 A&&... args
97)
98{
99 return std::async(std::launch::async, [=]() {
100 std::this_thread::sleep_for(delay);
101 return f(std::forward<A>(args)...);
102 });
103}
104
105/**
106 *
107 * @brief Executes a function asynchronously with a timeout.
108 *
109 * This function executes the given function `f` asynchronously, along with its
110 * arguments `args`, and provides a timeout mechanism. If the function does not
111 * complete within the specified timeout duration, an exception is thrown.
112 *
113 * @tparam R The type of the timeout duration.
114 * @tparam P The type of the timeout duration.
115 * @tparam F The type of the function to be executed.
116 * @tparam A The types of the arguments to the function.
117 *
118 * @param timeout The timeout duration for the function execution.
119 * @param f The function to be executed.
120 * @param args The arguments to the function.
121 *
122 * @return std::future<typename std::result_of<F(A...)>::type> A future object
123 * representing the result of the function call.
124 *
125 * @throw std::runtime_error Thrown if the function execution exceeds the
126 * specified timeout duration.
127 *
128 */
129template<typename R, typename P, typename F, typename... A>
130std::future<typename std::result_of<F(A...)>::type> ldvc_async_execute_with_timeout(
131 const std::chrono::duration<R, P>& timeout,
132 F&& f,
133 A&&... args
134)
135{
136 std::promise<typename std::result_of<F(A...)>::type> promise;
137 std::future<typename std::result_of<F(A...)>::type> result = promise.get_future();
138
139 std::thread([=, &promise]() {
140 try {
141 f(std::forward<A>(args)...);
142 } catch (...) {
143 promise.set_exception(std::current_exception());
144 return;
145 }
146 promise.set_value();
147 }).detach();
148
149 std::thread([=, &promise]() {
150 std::this_thread::sleep_for(timeout);
151 promise.set_exception(std::make_exception_ptr(std::runtime_error("Timeout")));
152 }).detach();
153
154 return result;
155}
156
157#endif
std::future< typename std::result_of< F(A...)>::type > ldvc_async_execute_with_delay(const std::chrono::duration< R, P > &delay, F &&f, A &&... args)
Executes a function asynchronously with a delay.
std::future< typename std::result_of< F(A...)>::type > ldvc_async_execute_with_timeout(const std::chrono::duration< R, P > &timeout, F &&f, A &&... args)
Executes a function asynchronously with a timeout.
std::future< typename std::result_of< F(A...)>::type > ldvc_async_execute(F &&f, A &&... args)
Executes a function asynchronously.