uvw 2.12.1
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 "emitter.h"
15#include "util.h"
16
17namespace uvw {
18
19class AsyncHandle;
20class CheckHandle;
21class FsEventHandle;
22class FsPollHandle;
23class IdleHandle;
24class PipeHandle;
25class PollHandle;
26class PrepareHandle;
27class ProcessHandle;
28class SignalHandle;
29class TCPHandle;
30class TimerHandle;
31class TTYHandle;
32class UDPHandle;
33
34namespace details {
35
36enum class UVLoopOption : std::underlying_type_t<uv_loop_option> {
37 BLOCK_SIGNAL = UV_LOOP_BLOCK_SIGNAL,
38 IDLE_TIME = UV_METRICS_IDLE_TIME
39};
40
41enum class UVRunMode : std::underlying_type_t<uv_run_mode> {
42 DEFAULT = UV_RUN_DEFAULT,
43 ONCE = UV_RUN_ONCE,
44 NOWAIT = UV_RUN_NOWAIT
45};
46
47} // namespace details
48
57class Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop> {
58 using Deleter = void (*)(uv_loop_t *);
59
60 template<typename, typename>
61 friend class Resource;
62
63 template<typename R, typename... Args>
64 auto create_resource(int, Args &&...args) -> decltype(std::declval<R>().init(), std::shared_ptr<R>{}) {
65 auto ptr = R::create(shared_from_this(), std::forward<Args>(args)...);
66 ptr = ptr->init() ? ptr : nullptr;
67 return ptr;
68 }
69
70 template<typename R, typename... Args>
71 std::shared_ptr<R> create_resource(char, Args &&...args) {
72 return R::create(shared_from_this(), std::forward<Args>(args)...);
73 }
74
75 Loop(std::unique_ptr<uv_loop_t, Deleter> ptr) noexcept;
76
77public:
78 using Time = std::chrono::duration<uint64_t, std::milli>;
79 using Configure = details::UVLoopOption;
80 using Mode = details::UVRunMode;
81
86 static std::shared_ptr<Loop> create();
87
98 static std::shared_ptr<Loop> create(uv_loop_t *loop);
99
112 static std::shared_ptr<Loop> getDefault();
113
114 Loop(const Loop &) = delete;
115 Loop(Loop &&other) = delete;
116
117 Loop &operator=(const Loop &) = delete;
118 Loop &operator=(Loop &&other) = delete;
119
120 ~Loop() noexcept;
121
141 template<typename... Args>
142 void configure(Configure flag, Args &&...args) {
143 auto option = static_cast<std::underlying_type_t<Configure>>(flag);
144 auto err = uv_loop_configure(loop.get(), static_cast<uv_loop_option>(option), std::forward<Args>(args)...);
145 if(err) { publish(ErrorEvent{err}); }
146 }
147
158 template<typename R, typename... Args>
159 std::shared_ptr<R> resource(Args &&...args) {
160 return create_resource<R>(0, std::forward<Args>(args)...);
161 }
162
171 void close();
172
191 template<Mode mode = Mode::DEFAULT>
192 bool run() noexcept;
193
198 bool alive() const noexcept;
199
208 void stop() noexcept;
209
219 int descriptor() const noexcept;
220
227 std::pair<bool, Time> timeout() const noexcept;
228
234 Time idleTime() const noexcept;
235
248 Time now() const noexcept;
249
259 void update() const noexcept;
260
268 template<typename Func>
269 void walk(Func callback) {
270 auto func = [](uv_handle_t *handle, void *func) {
271 if(handle->data) {
272 auto &cb = *static_cast<Func *>(func);
273
274 switch(Utilities::guessHandle(HandleCategory{handle->type})) {
275 case HandleType::ASYNC:
276 cb(*static_cast<AsyncHandle *>(handle->data));
277 break;
278 case HandleType::CHECK:
279 cb(*static_cast<CheckHandle *>(handle->data));
280 break;
281 case HandleType::FS_EVENT:
282 cb(*static_cast<FsEventHandle *>(handle->data));
283 break;
284 case HandleType::FS_POLL:
285 cb(*static_cast<FsPollHandle *>(handle->data));
286 break;
287 case HandleType::IDLE:
288 cb(*static_cast<IdleHandle *>(handle->data));
289 break;
290 case HandleType::PIPE:
291 cb(*static_cast<PipeHandle *>(handle->data));
292 break;
293 case HandleType::POLL:
294 cb(*static_cast<PollHandle *>(handle->data));
295 break;
296 case HandleType::PREPARE:
297 cb(*static_cast<PrepareHandle *>(handle->data));
298 break;
299 case HandleType::PROCESS:
300 cb(*static_cast<ProcessHandle *>(handle->data));
301 break;
302 case HandleType::SIGNAL:
303 cb(*static_cast<SignalHandle *>(handle->data));
304 break;
305 case HandleType::TCP:
306 cb(*static_cast<TCPHandle *>(handle->data));
307 break;
308 case HandleType::TIMER:
309 cb(*static_cast<TimerHandle *>(handle->data));
310 break;
311 case HandleType::TTY:
312 cb(*static_cast<TTYHandle *>(handle->data));
313 break;
314 case HandleType::UDP:
315 cb(*static_cast<UDPHandle *>(handle->data));
316 break;
317 default:
318 // this handle isn't managed by uvw, let it be...
319 break;
320 }
321 }
322 };
323
324 uv_walk(loop.get(), func, &callback);
325 }
326
357 void fork() noexcept;
358
363 template<typename R = void>
364 std::shared_ptr<R> data() const {
365 return std::static_pointer_cast<R>(userData);
366 }
367
372 void data(std::shared_ptr<void> uData);
373
389 const uv_loop_t *raw() const noexcept;
390
406 uv_loop_t *raw() noexcept;
407
408private:
409 std::unique_ptr<uv_loop_t, Deleter> loop;
410 std::shared_ptr<void> userData{nullptr};
411};
412
413// (extern) explicit instantiations
414#ifdef UVW_AS_LIB
415extern template bool Loop::run<Loop::Mode::DEFAULT>() noexcept;
416extern template bool Loop::run<Loop::Mode::ONCE>() noexcept;
417extern template bool Loop::run<Loop::Mode::NOWAIT>() noexcept;
418#endif // UVW_AS_LIB
419
420} // namespace uvw
421
422#ifndef UVW_AS_LIB
423# include "loop.cpp"
424#endif
425
426#endif // UVW_LOOP_INCLUDE_H
The AsyncHandle handle.
Definition async.h:25
The CheckHandle handle.
Definition check.h:25
Event emitter base class.
Definition emitter.h:83
The FsEventHandle handle.
Definition fs_event.h:68
The FsPollHandle handle.
Definition fs_poll.h:34
The IdleHandle handle.
Definition idle.h:33
The Loop class.
Definition loop.h:57
void update() const noexcept
Updates the event loop’s concept of now.
static std::shared_ptr< Loop > getDefault()
Gets the initialized default loop.
void 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:159
static std::shared_ptr< Loop > create(uv_loop_t *loop)
Initializes a new Loop instance from an existing resource.
const uv_loop_t * raw() const noexcept
Gets the underlying raw data structure.
void walk(Func callback)
Walks the list of handles.
Definition loop.h:269
static std::shared_ptr< Loop > create()
Initializes a new Loop instance.
void configure(Configure flag, Args &&...args)
Sets additional loop options.
Definition loop.h:142
void data(std::shared_ptr< void > uData)
Sets arbitrary data. uvw won't use this field in any case.
void stop() noexcept
Stops the event loop.
bool run() noexcept
Runs the event loop.
Time idleTime() const noexcept
Returns the amount of time the event loop has been idle. The call is thread safe.
std::shared_ptr< R > data() const
Gets user-defined data. uvw won't use this field in any case.
Definition loop.h:364
Time now() const noexcept
Returns the current timestamp in milliseconds.
int descriptor() const noexcept
Get backend file descriptor.
std::pair< bool, Time > timeout() const noexcept
Gets the poll timeout.
bool alive() const noexcept
Checks if there are active resources.
void close()
Releases all internal loop resources.
The PipeHandle handle.
Definition pipe.h:35
The PollHandle handle.
Definition poll.h:60
The PrepareHandle handle.
Definition prepare.h:25
The ProcessHandle handle.
Definition process.h:58
Common class for almost all the resources available in uvw.
Definition resource.hpp:17
The SignalHandle handle.
Definition signal.h:34
The TCPHandle handle.
Definition tcp.h:40
The TTYHandle handle.
Definition tty.h:49
The TimerHandle handle.
Definition timer.h:26
The UDPHandle handle.
Definition udp.h:85
uvw default namespace.
Definition async.h:8
details::UVTypeWrapper< uv_handle_type > HandleCategory
Definition util.h:204
The ErrorEvent event.
Definition emitter.h:23
static HandleType guessHandle(HandleCategory category) noexcept
Gets the type of the handle given a category.