8 #ifndef WPIUTIL_WPI_UV_ASYNCFUNCTION_H_
9 #define WPIUTIL_WPI_UV_ASYNCFUNCTION_H_
21 #include "wpi/STLExtras.h"
22 #include "wpi/condition_variable.h"
23 #include "wpi/mutex.h"
24 #include "wpi/uv/Handle.h"
25 #include "wpi/uv/Loop.h"
36 m_resultCv.notify_all();
41 std::atomic_bool m_active{
true};
42 wpi::condition_variable m_resultCv;
45 template <
typename R,
typename... T>
47 inline void RunCall(
const std::function<R(T...)>& func,
48 std::pair<std::thread::id, std::tuple<T...>>& v) {
49 m_results.emplace_back(
50 std::piecewise_construct, std::forward_as_tuple(v.first),
51 std::forward_as_tuple(
apply_tuple(func, std::move(v.second))));
54 inline R GetCallResult(std::thread::id from) {
56 std::unique_lock<wpi::mutex> lock(m_mutex);
59 auto it = std::find_if(m_results.begin(), m_results.end(),
60 [=](
const auto& r) {
return r.first == from; });
61 if (it != m_results.end()) {
63 auto rv = std::move(it->second);
68 m_resultCv.wait(lock);
75 std::vector<std::pair<std::thread::id, R>> m_results;
79 template <
typename... T>
81 inline void RunCall(
const std::function<
void(T...)>& func,
82 std::pair<std::thread::id, std::tuple<T...>>& v) {
84 m_results.emplace_back(v.first);
87 inline void GetCallResult(std::thread::id from) {
89 std::unique_lock<wpi::mutex> lock(m_mutex);
92 auto it = std::find(m_results.begin(), m_results.end(), from);
93 if (it != m_results.end()) {
99 m_resultCv.wait(lock);
104 std::vector<std::thread::id> m_results;
109 template <
typename T>
117 template <
typename R,
typename... T>
119 :
public HandleImpl<AsyncFunction<R(T...)>, uv_async_t>,
121 struct private_init {};
124 AsyncFunction(std::function<R(T...)> func,
const private_init&)
134 static std::shared_ptr<AsyncFunction>
Create(
135 Loop& loop, std::function<R(T...)> func =
nullptr) {
136 auto h = std::make_shared<AsyncFunction>(std::move(func), private_init{});
137 int err = uv_async_init(loop.
GetRaw(), h->GetRaw(), [](
uv_async_t* handle) {
139 std::lock_guard<wpi::mutex> lock(h.m_mutex);
141 if (!h.m_params.empty()) {
143 for (
auto&& v : h.m_params) {
146 if (v.first == std::thread::id{})
149 h.RunCall(h.wakeup, v);
153 h.m_resultCv.notify_all();
170 static std::shared_ptr<AsyncFunction>
Create(
171 const std::shared_ptr<Loop>& loop,
172 std::function<R(T...)> func =
nullptr) {
173 return Create(*loop, std::move(func));
183 template <
typename... U>
187 std::lock_guard<wpi::mutex> lock(this->m_mutex);
188 m_params.emplace_back(std::piecewise_construct,
189 std::forward_as_tuple(std::thread::id{}),
190 std::forward_as_tuple(std::forward<U>(u)...));
194 this->Invoke(&uv_async_send, this->GetRaw());
207 template <
typename... U>
209 std::thread::id from = std::this_thread::get_id();
213 std::lock_guard<wpi::mutex> lock(this->m_mutex);
214 m_params.emplace_back(std::piecewise_construct,
215 std::forward_as_tuple(from),
216 std::forward_as_tuple(std::forward<U>(u)...));
220 this->Invoke(&uv_async_send, this->GetRaw());
223 return this->GetCallResult(from);
232 std::vector<std::pair<std::thread::id, std::tuple<T...>>> m_params;
238 #endif // WPIUTIL_WPI_UV_ASYNCFUNCTION_H_
Definition: AsyncFunction.h:110
static std::shared_ptr< AsyncFunction > Create(Loop &loop, std::function< R(T...)> func=nullptr)
Create an async handle.
Definition: AsyncFunction.h:134
Handle.
Definition: Handle.h:246
void Send(U &&...u)
Wakeup the event loop, call the async function, and ignore any result.
Definition: AsyncFunction.h:184
Definition: AsyncFunction.h:46
void ReportError(int err)
Reports error.
Definition: Loop.h:235
uv_loop_t * GetRaw() const noexcept
Get the underlying event loop data structure.
Definition: Loop.h:209
WPILib C++ utilities (wpiutil) namespace.
Definition: SmallString.h:21
std::function< R(T...)> wakeup
Function called (on event loop thread) when the async is called.
Definition: AsyncFunction.h:229
auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(std::forward< F >(f), std::forward< Tuple >(t), build_index_impl< std::tuple_size< typename std::decay< Tuple >::type >::value >
Given an input tuple (a1, a2, ..., an), pass the arguments of the tuple variadically to f as if by ca...
Definition: STLExtras.h:1209
Event loop.
Definition: Loop.h:37
R Call(U &&...u)
Wakeup the event loop, call the async function, and return the result.
Definition: AsyncFunction.h:208
static std::shared_ptr< AsyncFunction > Create(const std::shared_ptr< Loop > &loop, std::function< R(T...)> func=nullptr)
Create an async handle.
Definition: AsyncFunction.h:170
Definition: AsyncFunction.h:32