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())) {
182 static std::shared_ptr<Loop>
create(uv_loop_t *loop) {
183 auto ptr = std::unique_ptr<uv_loop_t, Deleter>{loop, [](uv_loop_t *){}};
184 return std::shared_ptr<Loop>{
new Loop{std::move(ptr)}};
200 static std::weak_ptr<Loop> ref;
201 std::shared_ptr<Loop> loop;
204 auto def = uv_default_loop();
207 auto ptr = std::unique_ptr<uv_loop_t, Deleter>(def, [](uv_loop_t *){});
208 loop = std::shared_ptr<Loop>{
new Loop{std::move(ptr)}};
221 Loop & operator=(
const Loop &) =
delete;
222 Loop & operator=(
Loop &&other) =
delete;
246 template<
typename... Args>
248 auto option =
static_cast<std::underlying_type_t<Configure>
>(flag);
249 auto err = uv_loop_configure(loop.get(),
static_cast<uv_loop_option
>(option), std::forward<Args>(args)...);
263 template<
typename R,
typename... Args>
265 if constexpr(std::is_base_of_v<BaseHandle, R>) {
266 auto ptr = R::create(shared_from_this(), std::forward<Args>(args)...);
267 ptr = ptr->init() ? ptr :
nullptr;
270 return R::create(shared_from_this(), std::forward<Args>(args)...);
283 auto err = uv_loop_close(loop.get());
284 return err ? publish(
ErrorEvent{err}) : loop.reset();
305 template<Mode mode = Mode::DEFAULT>
307 auto utm =
static_cast<std::underlying_type_t<Mode>
>(mode);
308 auto uvrm =
static_cast<uv_run_mode
>(utm);
309 return (uv_run(loop.get(), uvrm) == 0);
317 return !(uv_loop_alive(loop.get()) == 0);
342 return uv_backend_fd(loop.get());
351 std::pair<bool, Time>
timeout() const noexcept {
352 auto to = uv_backend_timeout(loop.get());
353 return std::make_pair(to == -1, Time{to});
368 Time
now() const noexcept {
369 return Time{uv_now(loop.get())};
382 return uv_update_time(loop.get());
394 uv_walk(loop.get(), [](uv_handle_t *handle,
void *func) {
396 std::function<void(BaseHandle &)> &f =
397 *
static_cast<std::function<void(BaseHandle &)>*
>(func);
433 auto err = uv_loop_fork(loop.get());
441 template<
typename R =
void>
442 std::shared_ptr<R>
data()
const {
443 return std::static_pointer_cast<R>(userData);
450 void data(std::shared_ptr<void> uData) {
451 userData = std::move(uData);
469 const uv_loop_t *
raw() const noexcept {
488 uv_loop_t *
raw() noexcept {
489 return const_cast<uv_loop_t *
>(
const_cast<const Loop *
>(
this)->raw());
493 std::unique_ptr<uv_loop_t, Deleter> loop;
494 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.
static std::shared_ptr< Loop > create(uv_loop_t *loop)
Initializes a new Loop instance from an existing resource.
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.