8 #ifndef WPIUTIL_WPI_UV_ASYNCFUNCTION_H_
9 #define WPIUTIL_WPI_UV_ASYNCFUNCTION_H_
21 #include "wpi/STLExtras.h"
22 #include "wpi/future.h"
23 #include "wpi/mutex.h"
24 #include "wpi/uv/Handle.h"
25 #include "wpi/uv/Loop.h"
38 template <
typename R,
typename... T>
40 :
public HandleImpl<AsyncFunction<R(T...)>, uv_async_t> {
41 struct private_init {};
45 std::function<
void(
promise<R>, T...)> func,
const private_init&)
46 : wakeup{func}, m_loop{loop} {}
48 if (
auto loop = m_loop.lock())
63 static std::shared_ptr<AsyncFunction>
Create(
64 Loop& loop, std::function<
void(
promise<R>, T...)> func =
nullptr) {
65 return Create(loop.shared_from_this(), std::move(func));
77 static std::shared_ptr<AsyncFunction>
Create(
78 const std::shared_ptr<Loop>& loop,
79 std::function<
void(
promise<R>, T...)> func =
nullptr) {
81 std::make_shared<AsyncFunction>(loop, std::move(func), private_init{});
83 uv_async_init(loop->GetRaw(), h->GetRaw(), [](
uv_async_t* handle) {
85 std::unique_lock<wpi::mutex> lock(h.m_mutex);
87 if (!h.m_params.empty()) {
91 for (
auto&& v : h.m_params) {
92 auto p = h.m_promises.CreatePromise(v.first);
95 std::tuple_cat(std::make_tuple(std::move(p)),
96 std::move(v.second)));
101 h.m_promises.Notify();
105 loop->ReportError(err);
122 template <
typename... U>
125 uint64_t req = m_promises.CreateRequest();
127 auto loop = m_loop.lock();
128 if (loop && loop->GetThreadId() == std::this_thread::get_id()) {
130 wakeup(m_promises.CreatePromise(req), std::forward<U>(u)...);
131 return m_promises.CreateFuture(req);
136 std::lock_guard<wpi::mutex> lock(m_mutex);
137 m_params.emplace_back(std::piecewise_construct,
138 std::forward_as_tuple(req),
139 std::forward_as_tuple(std::forward<U>(u)...));
143 if (loop) this->Invoke(&uv_async_send, this->GetRaw());
146 return m_promises.CreateFuture(req);
149 template <
typename... U>
151 return Call(std::forward<U>(u)...);
157 std::function<void(promise<R>, T...)>
wakeup;
161 std::vector<std::pair<uint64_t, std::tuple<T...>>> m_params;
163 std::weak_ptr<Loop> m_loop;
169 #endif // WPIUTIL_WPI_UV_ASYNCFUNCTION_H_
future< R > Call(U &&...u)
Wakeup the event loop, call the async function, and return a future for the result.
Definition: AsyncFunction.h:123
Definition: AsyncFunction.h:31
static std::shared_ptr< AsyncFunction > Create(const std::shared_ptr< Loop > &loop, std::function< void(promise< R >, T...)> func=nullptr)
Create an async handle.
Definition: AsyncFunction.h:77
Handle.
Definition: Handle.h:249
WPILib C++ utilities (wpiutil) namespace.
Definition: SmallString.h:21
A lightweight version of std::promise.
Definition: future.h:33
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
static std::shared_ptr< AsyncFunction > Create(Loop &loop, std::function< void(promise< R >, T...)> func=nullptr)
Create an async handle.
Definition: AsyncFunction.h:63
Event loop.
Definition: Loop.h:39
A lightweight version of std::future.
Definition: future.h:30
std::function< void(promise< R >, T...)> wakeup
Function called (on event loop thread) when the async is called.
Definition: AsyncFunction.h:157