uvw  2.11.0
loop.h
1 #ifndef UVW_LOOP_INCLUDE_H
2 #define UVW_LOOP_INCLUDE_H
3 
4 
5 #ifdef _WIN32
6 #include <ciso646>
7 #endif
8 
9 #include <functional>
10 #include <memory>
11 #include <utility>
12 #include <type_traits>
13 #include <chrono>
14 #include <uv.h>
15 #include "emitter.h"
16 #include "util.h"
17 
18 
19 namespace uvw {
20 
21 
22 class AsyncHandle;
23 class CheckHandle;
24 class FsEventHandle;
25 class FsPollHandle;
26 class IdleHandle;
27 class PipeHandle;
28 class PollHandle;
29 class PrepareHandle;
30 class ProcessHandle;
31 class SignalHandle;
32 class TCPHandle;
33 class TimerHandle;
34 class TTYHandle;
35 class UDPHandle;
36 
37 
38 namespace details {
39 
40 
41 enum class UVLoopOption: std::underlying_type_t<uv_loop_option> {
42  BLOCK_SIGNAL = UV_LOOP_BLOCK_SIGNAL,
43  IDLE_TIME = UV_METRICS_IDLE_TIME
44 };
45 
46 
47 enum class UVRunMode: std::underlying_type_t<uv_run_mode> {
48  DEFAULT = UV_RUN_DEFAULT,
49  ONCE = UV_RUN_ONCE,
50  NOWAIT = UV_RUN_NOWAIT
51 };
52 
53 
54 }
55 
56 
65 class Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop> {
66  using Deleter = void(*)(uv_loop_t *);
67 
68  template<typename, typename>
69  friend class Resource;
70 
71  template<typename R, typename... Args>
72  auto create_resource(int, Args&&... args) -> decltype(std::declval<R>().init(), std::shared_ptr<R>{}) {
73  auto ptr = R::create(shared_from_this(), std::forward<Args>(args)...);
74  ptr = ptr->init() ? ptr : nullptr;
75  return ptr;
76  }
77 
78  template<typename R, typename... Args>
79  std::shared_ptr<R> create_resource(char, Args&&... args) {
80  return R::create(shared_from_this(), std::forward<Args>(args)...);
81  }
82 
83  Loop(std::unique_ptr<uv_loop_t, Deleter> ptr) noexcept;
84 
85 public:
86  using Time = std::chrono::duration<uint64_t, std::milli>;
87  using Configure = details::UVLoopOption;
88  using Mode = details::UVRunMode;
89 
94  static std::shared_ptr<Loop> create();
95 
106  static std::shared_ptr<Loop> create(uv_loop_t *loop);
107 
120  static std::shared_ptr<Loop> getDefault();
121 
122  Loop(const Loop &) = delete;
123  Loop(Loop &&other) = delete;
124  Loop & operator=(const Loop &) = delete;
125  Loop & operator=(Loop &&other) = delete;
126 
127  ~Loop() noexcept;
128 
148  template<typename... Args>
149  void configure(Configure flag, Args&&... args) {
150  auto option = static_cast<std::underlying_type_t<Configure>>(flag);
151  auto err = uv_loop_configure(loop.get(), static_cast<uv_loop_option>(option), std::forward<Args>(args)...);
152  if(err) { publish(ErrorEvent{err}); }
153  }
154 
165  template<typename R, typename... Args>
166  std::shared_ptr<R> resource(Args&&... args) {
167  return create_resource<R>(0, std::forward<Args>(args)...);
168  }
169 
178  void close();
179 
198  template<Mode mode = Mode::DEFAULT>
199  bool run() noexcept;
200 
205  bool alive() const noexcept;
206 
215  void stop() noexcept;
216 
226  int descriptor() const noexcept;
227 
234  std::pair<bool, Time> timeout() const noexcept;
235 
241  Time idleTime() const noexcept;
242 
255  Time now() const noexcept;
256 
266  void update() const noexcept;
267 
275  template<typename Func>
276  void walk(Func callback) {
277  // remember: non-capturing lambdas decay to pointers to functions
278  uv_walk(loop.get(), [](uv_handle_t *handle, void *func) {
279  if(handle->data) {
280  auto &cb = *static_cast<Func *>(func);
281 
282  switch(Utilities::guessHandle(HandleCategory{handle->type})) {
283  case HandleType::ASYNC:
284  cb(*static_cast<AsyncHandle *>(handle->data));
285  break;
286  case HandleType::CHECK:
287  cb(*static_cast<CheckHandle *>(handle->data));
288  break;
289  case HandleType::FS_EVENT:
290  cb(*static_cast<FsEventHandle *>(handle->data));
291  break;
292  case HandleType::FS_POLL:
293  cb(*static_cast<FsPollHandle *>(handle->data));
294  break;
295  case HandleType::IDLE:
296  cb(*static_cast<IdleHandle *>(handle->data));
297  break;
298  case HandleType::PIPE:
299  cb(*static_cast<PipeHandle *>(handle->data));
300  break;
301  case HandleType::POLL:
302  cb(*static_cast<PollHandle *>(handle->data));
303  break;
304  case HandleType::PREPARE:
305  cb(*static_cast<PrepareHandle *>(handle->data));
306  break;
307  case HandleType::PROCESS:
308  cb(*static_cast<ProcessHandle *>(handle->data));
309  break;
310  case HandleType::SIGNAL:
311  cb(*static_cast<SignalHandle *>(handle->data));
312  break;
313  case HandleType::TCP:
314  cb(*static_cast<TCPHandle *>(handle->data));
315  break;
316  case HandleType::TIMER:
317  cb(*static_cast<TimerHandle *>(handle->data));
318  break;
319  case HandleType::TTY:
320  cb(*static_cast<TTYHandle *>(handle->data));
321  break;
322  case HandleType::UDP:
323  cb(*static_cast<UDPHandle *>(handle->data));
324  break;
325  default:
326  // this handle isn't managed by uvw, let it be...
327  break;
328  }
329  }
330  }, &callback);
331  }
332 
363  void fork() noexcept;
364 
369  template<typename R = void>
370  std::shared_ptr<R> data() const {
371  return std::static_pointer_cast<R>(userData);
372  }
373 
378  void data(std::shared_ptr<void> uData);
379 
395  const uv_loop_t * raw() const noexcept;
396 
412  uv_loop_t * raw() noexcept;
413 
414 private:
415  std::unique_ptr<uv_loop_t, Deleter> loop;
416  std::shared_ptr<void> userData{nullptr};
417 };
418 
419 
420 // (extern) explicit instantiations
421 #ifdef UVW_AS_LIB
422 extern template bool Loop::run<Loop::Mode::DEFAULT>() noexcept;
423 extern template bool Loop::run<Loop::Mode::ONCE>() noexcept;
424 extern template bool Loop::run<Loop::Mode::NOWAIT>() noexcept;
425 #endif // UVW_AS_LIB
426 
427 }
428 
429 
430 #ifndef UVW_AS_LIB
431 #include "loop.cpp"
432 #endif
433 
434 #endif // UVW_LOOP_INCLUDE_H
Event emitter base class.
Definition: emitter.h:87
The Loop class.
Definition: loop.h:65
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:166
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:276
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.
void configure(Configure flag, Args &&... args)
Sets additional loop options.
Definition: loop.h:149
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.
Common class for almost all the resources available in uvw.
Definition: resource.hpp:20
uvw default namespace.
Definition: async.h:10
The ErrorEvent event.
Definition: emitter.h:25