uvw  2.12.1
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 
17 namespace uvw {
18 
19 class AsyncHandle;
20 class CheckHandle;
21 class FsEventHandle;
22 class FsPollHandle;
23 class IdleHandle;
24 class PipeHandle;
25 class PollHandle;
26 class PrepareHandle;
27 class ProcessHandle;
28 class SignalHandle;
29 class TCPHandle;
30 class TimerHandle;
31 class TTYHandle;
32 class UDPHandle;
33 
34 namespace details {
35 
36 enum 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 
41 enum 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 
57 class 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 
77 public:
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 
408 private:
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
415 extern template bool Loop::run<Loop::Mode::DEFAULT>() noexcept;
416 extern template bool Loop::run<Loop::Mode::ONCE>() noexcept;
417 extern 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:82
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
std::shared_ptr< R > data() const
Gets user-defined data. uvw won't use this field in any case.
Definition: loop.h:364
void update() const noexcept
Updates the event loop’s concept of now.
void fork() noexcept
Reinitialize any kernel state necessary in the child process after a fork(2) system call.
static std::shared_ptr< Loop > getDefault()
Gets the initialized default loop.
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.
void walk(Func callback)
Walks the list of handles.
Definition: loop.h:269
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.
std::pair< bool, Time > timeout() const noexcept
Gets the poll timeout.
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.
Time now() const noexcept
Returns the current timestamp in milliseconds.
const uv_loop_t * raw() const noexcept
Gets the underlying raw data structure.
int descriptor() const noexcept
Get backend file descriptor.
bool alive() const noexcept
Checks if there are active resources.
void close()
Releases all internal loop resources.
static std::shared_ptr< Loop > create()
Initializes a new Loop instance.
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:25
The UDPHandle handle.
Definition: udp.h:85
uvw default namespace.
Definition: async.h:8
details::UVTypeWrapper< uv_handle_type > HandleCategory
Definition: util.h:203
The ErrorEvent event.
Definition: emitter.h:22
static HandleType guessHandle(HandleCategory category) noexcept
Gets the type of the handle given a category.