5#ifndef WPINET_UV_ASYNCFUNCTION_H_
6#define WPINET_UV_ASYNCFUNCTION_H_
35template <
typename R,
typename... T>
37 :
public HandleImpl<AsyncFunction<R(T...)>, uv_async_t> {
38 struct private_init {};
42 std::function<
void(
promise<R>, T...)> func,
const private_init&)
43 : wakeup{
std::move(func)}, m_loop{loop} {}
45 if (
auto loop = m_loop.lock()) {
61 static std::shared_ptr<AsyncFunction>
Create(
62 Loop& loop, std::function<
void(
promise<R>, T...)> func =
nullptr) {
63 return Create(loop.shared_from_this(), std::move(func));
75 static std::shared_ptr<AsyncFunction>
Create(
76 const std::shared_ptr<Loop>& loop,
77 std::function<
void(
promise<R>, T...)> func =
nullptr) {
78 if (loop->IsClosing()) {
82 std::make_shared<AsyncFunction>(loop, std::move(func), private_init{});
85 auto& h = *static_cast<AsyncFunction*>(handle->data);
86 std::unique_lock lock(h.m_mutex);
88 if (!h.m_params.empty()) {
92 for (auto&& v : h.m_params) {
93 auto p = h.m_promises.CreatePromise(v.first);
96 std::tuple_cat(std::make_tuple(std::move(p)),
97 std::move(v.second)));
103 h.m_promises.Notify();
107 loop->ReportError(err);
124 template <
typename... U>
127 uint64_t req = m_promises.CreateRequest();
129 auto loop = m_loop.lock();
130 if (loop->IsClosing()) {
131 if constexpr (std::same_as<R, void>) {
132 return m_promises.MakeReadyFuture();
134 return m_promises.MakeReadyFuture({});
137 if (loop && loop->GetThreadId() == std::this_thread::get_id()) {
139 wakeup(m_promises.CreatePromise(req), std::forward<U>(u)...);
140 return m_promises.CreateFuture(req);
145 std::scoped_lock lock(m_mutex);
146 m_params.emplace_back(std::piecewise_construct,
147 std::forward_as_tuple(req),
148 std::forward_as_tuple(std::forward<U>(u)...));
157 return m_promises.CreateFuture(req);
160 template <
typename... U>
162 return Call(std::forward<U>(u)...);
172 std::vector<std::pair<uint64_t, std::tuple<T...>>> m_params;
174 std::weak_ptr<Loop> m_loop;
A lightweight version of std::future.
Definition: future.h:271
A lightweight version of std::promise.
Definition: future.h:528
future< R > operator()(U &&... u)
Definition: AsyncFunction.h:161
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:75
static std::shared_ptr< AsyncFunction > Create(Loop &loop, std::function< void(promise< R >, T...)> func=nullptr)
Create an async handle.
Definition: AsyncFunction.h:61
std::function< void(promise< R >, T...)> wakeup
Function called (on event loop thread) when the async is called.
Definition: AsyncFunction.h:168
AsyncFunction(const std::shared_ptr< Loop > &loop, std::function< void(promise< R >, T...)> func, const private_init &)
Definition: AsyncFunction.h:41
~AsyncFunction() noexcept override
Definition: AsyncFunction.h:44
future< R > Call(U &&... u)
Wakeup the event loop, call the async function, and return a future for the result.
Definition: AsyncFunction.h:125
Definition: AsyncFunction.h:28
Handle.
Definition: Handle.h:290
Event loop.
Definition: Loop.h:37
std::vector< uint8_t > GetRaw(NT_Handle subentry, std::span< const uint8_t > defaultValue)
Get the last published value.
static constexpr const unit_t< compound_unit< energy::joules, inverse< temperature::kelvin >, inverse< substance::moles > > > R(8.3144598)
Gas constant.
static constexpr const unit_t< compound_unit< energy::joule, time::seconds > > h(6.626070040e-34)
Planck constant.
Definition: WebSocket.h:27
::std::mutex mutex
Definition: mutex.h:17
UV_EXTERN int uv_async_init(uv_loop_t *, uv_async_t *async, uv_async_cb async_cb)
UV_EXTERN int uv_async_send(uv_async_t *async)