/
loop.cpp
151 lines (99 loc) · 3.19 KB
/
loop.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifdef UVW_AS_LIB
#include "loop.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE Loop::Loop(std::unique_ptr<uv_loop_t, Deleter> ptr) noexcept
: loop{std::move(ptr)}
{}
UVW_INLINE std::shared_ptr<Loop> Loop::create() {
auto ptr = std::unique_ptr<uv_loop_t, Deleter>{new uv_loop_t, [](uv_loop_t *l) {
delete l;
}};
auto loop = std::shared_ptr<Loop>{new Loop{std::move(ptr)}};
if(uv_loop_init(loop->loop.get())) {
loop = nullptr;
}
return loop;
}
UVW_INLINE std::shared_ptr<Loop> Loop::create(uv_loop_t *loop) {
auto ptr = std::unique_ptr<uv_loop_t, Deleter>{loop, [](uv_loop_t *) {}};
return std::shared_ptr<Loop>{new Loop{std::move(ptr)}};
}
UVW_INLINE std::shared_ptr<Loop> Loop::getDefault() {
static std::weak_ptr<Loop> ref;
std::shared_ptr<Loop> loop;
if(ref.expired()) {
auto def = uv_default_loop();
if(def) {
auto ptr = std::unique_ptr<uv_loop_t, Deleter>(def, [](uv_loop_t *) {});
loop = std::shared_ptr<Loop>{new Loop{std::move(ptr)}};
}
ref = loop;
} else {
loop = ref.lock();
}
return loop;
}
UVW_INLINE Loop::~Loop() noexcept {
if(loop) {
close();
}
}
UVW_INLINE void Loop::close() {
auto err = uv_loop_close(loop.get());
return err ? publish(ErrorEvent{err}) : loop.reset();
}
template<Loop::Mode mode>
bool Loop::run() noexcept {
auto utm = static_cast<std::underlying_type_t<Mode>>(mode);
auto uvrm = static_cast<uv_run_mode>(utm);
return (uv_run(loop.get(), uvrm) == 0);
}
UVW_INLINE bool Loop::alive() const noexcept {
return !(uv_loop_alive(loop.get()) == 0);
}
UVW_INLINE void Loop::stop() noexcept {
uv_stop(loop.get());
}
UVW_INLINE int Loop::descriptor() const noexcept {
return uv_backend_fd(loop.get());
}
UVW_INLINE std::pair<bool, Loop::Time> Loop::timeout() const noexcept {
auto to = uv_backend_timeout(loop.get());
return std::make_pair(to == -1, Time{to});
}
UVW_INLINE Loop::Time Loop::now() const noexcept {
return Time{uv_now(loop.get())};
}
UVW_INLINE void Loop::update() const noexcept {
return uv_update_time(loop.get());
}
UVW_INLINE void Loop::walk(std::function<void(BaseHandle &)> callback) {
// remember: non-capturing lambdas decay to pointers to functions
uv_walk(loop.get(), [](uv_handle_t *handle, void *func) {
BaseHandle &ref = *static_cast<BaseHandle *>(handle->data);
std::function<void(BaseHandle &)> &f = *static_cast<std::function<void(BaseHandle &)> *>(func);
f(ref);
}, &callback);
}
UVW_INLINE void Loop::fork() noexcept {
auto err = uv_loop_fork(loop.get());
if(err) {
publish(ErrorEvent{err});
}
}
UVW_INLINE void Loop::data(std::shared_ptr<void> uData) {
userData = std::move(uData);
}
UVW_INLINE const uv_loop_t *Loop::raw() const noexcept {
return loop.get();
}
UVW_INLINE uv_loop_t *Loop::raw() noexcept {
return const_cast<uv_loop_t *>(const_cast<const Loop *>(this)->raw());
}
// explicit instantiations
template bool Loop::run<Loop::Mode::DEFAULT>() noexcept;
template bool Loop::run<Loop::Mode::ONCE>() noexcept;
template bool Loop::run<Loop::Mode::NOWAIT>() noexcept;
}