11 #include <type_traits> 14 #include "emitter.hpp" 24 enum class UVLoopOption: std::underlying_type_t<uv_loop_option> {
25 BLOCK_SIGNAL = UV_LOOP_BLOCK_SIGNAL
29 enum class UVRunMode: std::underlying_type_t<uv_run_mode> {
30 DEFAULT = UV_RUN_DEFAULT,
32 NOWAIT = UV_RUN_NOWAIT
68 virtual HandleType type()
const noexcept = 0;
89 virtual bool active()
const noexcept = 0;
99 virtual bool closing()
const noexcept = 0;
107 virtual void reference() noexcept = 0;
115 virtual void unreference() noexcept = 0;
121 virtual bool referenced()
const noexcept = 0;
130 virtual void close() noexcept = 0;
142 class Loop final:
public Emitter<Loop>,
public std::enable_shared_from_this<Loop> {
143 using Deleter = void(*)(uv_loop_t *);
145 template<
typename,
typename>
148 Loop(std::unique_ptr<uv_loop_t, Deleter> ptr) noexcept
149 : loop{std::move(ptr)}
153 using Time = std::chrono::duration<uint64_t, std::milli>;
154 using Configure = details::UVLoopOption;
155 using Mode = details::UVRunMode;
162 auto ptr = std::unique_ptr<uv_loop_t, Deleter>{
new uv_loop_t, [](uv_loop_t *l){
delete l; }};
163 auto loop = std::shared_ptr<Loop>{
new Loop{std::move(ptr)}};
165 if(uv_loop_init(loop->loop.get())) {
185 static std::weak_ptr<Loop> ref;
186 std::shared_ptr<Loop> loop;
189 auto def = uv_default_loop();
192 auto ptr = std::unique_ptr<uv_loop_t, Deleter>(def, [](uv_loop_t *){});
193 loop = std::shared_ptr<Loop>{
new Loop{std::move(ptr)}};
206 Loop & operator=(
const Loop &) =
delete;
207 Loop & operator=(
Loop &&other) =
delete;
231 template<
typename... Args>
233 auto option =
static_cast<std::underlying_type_t<Configure>
>(flag);
234 auto err = uv_loop_configure(loop.get(),
static_cast<uv_loop_option
>(option), std::forward<Args>(args)...);
248 template<
typename R,
typename... Args>
250 if constexpr(std::is_base_of_v<BaseHandle, R>) {
251 auto ptr = R::create(shared_from_this(), std::forward<Args>(args)...);
252 ptr = ptr->init() ? ptr :
nullptr;
255 return R::create(shared_from_this(), std::forward<Args>(args)...);
268 auto err = uv_loop_close(loop.get());
269 return err ? publish(
ErrorEvent{err}) : loop.reset();
290 template<Mode mode = Mode::DEFAULT>
292 auto utm =
static_cast<std::underlying_type_t<Mode>
>(mode);
293 auto uvrm =
static_cast<uv_run_mode
>(utm);
294 return (uv_run(loop.get(), uvrm) == 0);
302 return !(uv_loop_alive(loop.get()) == 0);
327 return uv_backend_fd(loop.get());
336 std::pair<bool, Time>
timeout() const noexcept {
337 auto to = uv_backend_timeout(loop.get());
338 return std::make_pair(to == -1, Time{to});
353 Time
now() const noexcept {
354 return Time{uv_now(loop.get())};
367 return uv_update_time(loop.get());
379 uv_walk(loop.get(), [](uv_handle_t *handle,
void *func) {
381 std::function<void(BaseHandle &)> &f =
382 *
static_cast<std::function<void(BaseHandle &)>*
>(func);
418 auto err = uv_loop_fork(loop.get());
426 template<
typename R =
void>
427 std::shared_ptr<R>
data()
const {
428 return std::static_pointer_cast<R>(userData);
435 void data(std::shared_ptr<void> uData) {
436 userData = std::move(uData);
454 const uv_loop_t *
raw() const noexcept {
473 uv_loop_t *
raw() noexcept {
474 return const_cast<uv_loop_t *
>(
const_cast<const Loop *
>(
this)->raw());
478 std::unique_ptr<uv_loop_t, Deleter> loop;
479 std::shared_ptr<void> userData{
nullptr};
const uv_loop_t * raw() const noexcept
Gets the underlying raw data structure.
Event emitter base class.
int descriptor() const noexcept
Get backend file descriptor.
void fork() noexcept
Reinitialize any kernel state necessary in the child process after a fork(2) system call...
void update() const noexcept
Updates the event loop’s concept of now.
Time now() const noexcept
Returns the current timestamp in milliseconds.
bool run() noexcept
Runs the event loop.
std::shared_ptr< R > data() const
Gets user-defined data. uvw won't use this field in any case.
static std::shared_ptr< Loop > getDefault()
Gets the initialized default loop.
uv_loop_t * raw() noexcept
Gets the underlying raw data structure.
std::pair< bool, Time > timeout() const noexcept
Gets the poll timeout.
details::UVTypeWrapper< uv_handle_type > HandleCategory
void configure(Configure flag, Args &&... args)
Sets additional loop options.
Common class for almost all the resources available in uvw.
bool alive() const noexcept
Checks if there are active resources.
void stop() noexcept
Stops the event loop.
void data(std::shared_ptr< void > uData)
Sets arbitrary data. uvw won't use this field in any case.
static std::shared_ptr< Loop > create()
Initializes a new Loop instance.
void walk(std::function< void(BaseHandle &)> callback)
Walks the list of handles.
std::shared_ptr< R > resource(Args &&... args)
Creates resources of any type.
void close()
Releases all internal loop resources.