8 #ifndef WPIUTIL_WPI_UV_ASYNC_H_
9 #define WPIUTIL_WPI_UV_ASYNC_H_
19 #include "wpi/Signal.h"
20 #include "wpi/mutex.h"
21 #include "wpi/uv/Handle.h"
22 #include "wpi/uv/Loop.h"
38 template <
typename... T>
40 struct private_init {};
43 Async(
const std::shared_ptr<Loop>& loop,
const private_init&)
45 ~
Async() noexcept
override {
46 if (
auto loop = m_loop.lock())
58 return Create(loop.shared_from_this());
66 static std::shared_ptr<Async>
Create(
const std::shared_ptr<Loop>& loop) {
67 auto h = std::make_shared<Async>(loop, private_init{});
69 uv_async_init(loop->GetRaw(), h->GetRaw(), [](uv_async_t* handle) {
70 auto& h = *static_cast<Async*>(handle->data);
71 std::scoped_lock lock(h.m_mutex);
72 for (
auto&& v : h.m_data) std::apply(h.wakeup, v);
76 loop->ReportError(err);
89 template <
typename... U>
91 auto loop = m_loop.lock();
92 if (loop && loop->GetThreadId() == std::this_thread::get_id()) {
94 wakeup(std::forward<U>(u)...);
99 std::scoped_lock lock(m_mutex);
100 m_data.emplace_back(std::forward_as_tuple(std::forward<U>(u)...));
102 if (loop) this->Invoke(&uv_async_send, this->
GetRaw());
112 std::vector<std::tuple<T...>> m_data;
113 std::weak_ptr<Loop> m_loop;
122 struct private_init {};
125 Async(
const std::shared_ptr<Loop>& loop,
const private_init&)
127 ~
Async() noexcept
override;
135 return Create(loop.shared_from_this());
143 static std::shared_ptr<Async>
Create(
const std::shared_ptr<Loop>& loop);
152 if (
auto loop = m_loop.lock()) Invoke(&uv_async_send,
GetRaw());
161 std::weak_ptr<Loop> m_loop;
167 #endif // WPIUTIL_WPI_UV_ASYNC_H_