uvw 3.4.0
Loading...
Searching...
No Matches
loop.h
1#ifndef UVW_LOOP_INCLUDE_H
2#define UVW_LOOP_INCLUDE_H
3
4#ifdef _WIN32
5# include <ciso646>
6#endif
7
8#include <chrono>
9#include <functional>
10#include <memory>
11#include <type_traits>
12#include <utility>
13#include <uv.h>
14#include "config.h"
15#include "emitter.h"
16#include "util.h"
17
18namespace uvw {
19
20class async_handle;
21class check_handle;
22class fs_event_handle;
23class fs_poll_handle;
24class idle_handle;
25class pipe_handle;
26class poll_handle;
27class prepare_handle;
28class process_handle;
29class signal_handle;
30class tcp_handle;
31class timer_handle;
32class tty_handle;
33class udp_handle;
34
35namespace details {
36
37enum class uvw_loop_option : std::underlying_type_t<uv_loop_option> {
38 BLOCK_SIGNAL = UV_LOOP_BLOCK_SIGNAL,
39 IDLE_TIME = UV_METRICS_IDLE_TIME
40};
41
42enum class uvw_run_mode : std::underlying_type_t<uv_run_mode> {
43 DEFAULT = UV_RUN_DEFAULT,
44 ONCE = UV_RUN_ONCE,
45 NOWAIT = UV_RUN_NOWAIT
46};
47
48} // namespace details
49
50using metrics_type = uv_metrics_t;
51
60class loop final: public emitter<loop>, public std::enable_shared_from_this<loop> {
61 using deleter = void (*)(uv_loop_t *);
62
63 template<typename, typename, typename...>
64 friend class resource;
65
66 class uv_token {
67 friend class loop;
68 explicit uv_token(int) {}
69 };
70
71 template<typename Type>
72 auto init(int, Type &value) -> decltype(value.init()) {
73 return value.init();
74 }
75
76 template<typename Type>
77 int init(char, Type &) {
78 return 0;
79 }
80
81 loop(std::unique_ptr<uv_loop_t, deleter> ptr) noexcept;
82
83public:
84 using token = uv_token;
85 using time = std::chrono::duration<uint64_t, std::milli>;
86 using option = details::uvw_loop_option;
87 using run_mode = details::uvw_run_mode;
88
93 static std::shared_ptr<loop> create();
94
105 static std::shared_ptr<loop> create(uv_loop_t *res);
106
119 static std::shared_ptr<loop> get_default();
120
121 loop(const loop &) = delete;
122 loop(loop &&other) = delete;
123
124 loop &operator=(const loop &) = delete;
125 loop &operator=(loop &&other) = delete;
126
127 ~loop() noexcept;
128
148 template<typename... Args>
149 int configure(option flag, Args &&...args) {
150 return uv_loop_configure(uv_loop.get(), static_cast<uv_loop_option>(flag), std::forward<Args>(args)...);
151 }
152
163 template<typename R, typename... Args>
164 std::shared_ptr<R> resource(Args &&...args) {
165 auto ptr = uninitialized_resource<R>(std::forward<Args>(args)...);
166 return (init(0, *ptr) == 0) ? ptr : nullptr;
167 }
168
173 template<typename R, typename... Args>
174 std::shared_ptr<R> uninitialized_resource(Args &&...args) {
175 return std::make_shared<R>(token{0}, shared_from_this(), std::forward<Args>(args)...);
176 }
177
186 int close();
187
206 int run(run_mode mode = run_mode::DEFAULT) noexcept;
207
212 bool alive() const noexcept;
213
222 void stop() noexcept;
223
233 int descriptor() const noexcept;
234
241 std::pair<bool, time> timeout() const noexcept;
242
248 time idle_time() const noexcept;
249
254 metrics_type metrics() const noexcept;
255
268 time now() const noexcept;
269
279 void update() const noexcept;
280
288 template<typename Func>
289 void walk(Func callback) {
290 auto func = [](uv_handle_t *hndl, void *callback_func) {
291 if(hndl->data) {
292 auto &cb = *static_cast<Func *>(callback_func);
293
294 switch(utilities::guess_handle(handle_category{hndl->type})) {
295 case handle_type::ASYNC:
296 cb(*static_cast<async_handle *>(hndl->data));
297 break;
298 case handle_type::CHECK:
299 cb(*static_cast<check_handle *>(hndl->data));
300 break;
301 case handle_type::FS_EVENT:
302 cb(*static_cast<fs_event_handle *>(hndl->data));
303 break;
304 case handle_type::FS_POLL:
305 cb(*static_cast<fs_poll_handle *>(hndl->data));
306 break;
307 case handle_type::IDLE:
308 cb(*static_cast<idle_handle *>(hndl->data));
309 break;
310 case handle_type::PIPE:
311 cb(*static_cast<pipe_handle *>(hndl->data));
312 break;
313 case handle_type::POLL:
314 cb(*static_cast<poll_handle *>(hndl->data));
315 break;
316 case handle_type::PREPARE:
317 cb(*static_cast<prepare_handle *>(hndl->data));
318 break;
319 case handle_type::PROCESS:
320 cb(*static_cast<process_handle *>(hndl->data));
321 break;
322 case handle_type::SIGNAL:
323 cb(*static_cast<signal_handle *>(hndl->data));
324 break;
325 case handle_type::TCP:
326 cb(*static_cast<tcp_handle *>(hndl->data));
327 break;
328 case handle_type::TIMER:
329 cb(*static_cast<timer_handle *>(hndl->data));
330 break;
331 case handle_type::TTY:
332 cb(*static_cast<tty_handle *>(hndl->data));
333 break;
334 case handle_type::UDP:
335 cb(*static_cast<udp_handle *>(hndl->data));
336 break;
337 default:
338 // this handle isn't managed by uvw, let it be...
339 break;
340 }
341 }
342 };
343
344 uv_walk(uv_loop.get(), func, &callback);
345 }
346
377 int fork() noexcept;
378
383 template<typename R = void>
384 std::shared_ptr<R> data() const {
385 return std::static_pointer_cast<R>(user_data);
386 }
387
392 void data(std::shared_ptr<void> ud);
393
409 const uv_loop_t *raw() const noexcept;
410
426 uv_loop_t *raw() noexcept;
427
428private:
429 std::unique_ptr<uv_loop_t, deleter> uv_loop;
430 std::shared_ptr<void> user_data{nullptr};
431};
432
433} // namespace uvw
434
435#ifndef UVW_AS_LIB
436# include "loop.cpp"
437#endif
438
439#endif // UVW_LOOP_INCLUDE_H
The async handle.
Definition async.h:21
The check handle.
Definition check.h:21
Event emitter base class.
Definition emitter.h:83
The fs event handle.
Definition fs_event.h:67
The fs poll handle.
Definition fs_poll.h:31
The idle handle.
Definition idle.h:29
int run(run_mode mode=run_mode::DEFAULT) noexcept
Runs the event loop.
std::shared_ptr< R > data() const
Gets user-defined data. uvw won't use this field in any case.
Definition loop.h:384
metrics_type metrics() const noexcept
Tracks various internal operations of the event loop.
int fork() noexcept
Reinitialize any kernel state necessary in the child process after a fork(2) system call.
std::shared_ptr< R > resource(Args &&...args)
Creates resources of any type.
Definition loop.h:164
const uv_loop_t * raw() const noexcept
Gets the underlying raw data structure.
bool alive() const noexcept
Checks if there are active resources.
static std::shared_ptr< loop > get_default()
Gets the initialized default loop.
void update() const noexcept
Updates the event loop’s concept of now.
static std::shared_ptr< loop > create()
Initializes a new loop instance.
void data(std::shared_ptr< void > ud)
Sets arbitrary data. uvw won't use this field in any case.
std::pair< bool, time > timeout() const noexcept
Gets the poll timeout.
void walk(Func callback)
Walks the list of handles.
Definition loop.h:289
void stop() noexcept
Stops the event loop.
time now() const noexcept
Returns the current timestamp in milliseconds.
int close()
Releases all internal loop resources.
int configure(option flag, Args &&...args)
Sets additional loop options.
Definition loop.h:149
static std::shared_ptr< loop > create(uv_loop_t *res)
Initializes a new loop instance from an existing resource.
int descriptor() const noexcept
Get backend file descriptor.
time idle_time() const noexcept
Returns the amount of time the event loop has been idle. The call is thread safe.
std::shared_ptr< R > uninitialized_resource(Args &&...args)
Creates uninitialized resources of any type.
Definition loop.h:174
The pipe handle.
Definition pipe.h:38
The poll handle.
Definition poll.h:59
The prepare handle.
Definition prepare.h:21
The process handle.
Definition process.h:59
The signal handle.
Definition signal.h:31
The TCP handle.
Definition tcp.h:43
The timer handle.
Definition timer.h:22
The tty handle.
Definition tty.h:50
The UDP handle.
Definition udp.h:82
uvw default namespace.
Definition async.h:8
details::uv_type_wrapper< uv_handle_type > handle_category
Definition util.h:84
uv_metrics_t metrics_type
Definition loop.h:50
static handle_type guess_handle(handle_category category) noexcept
Gets the type of the handle given a category.