uvco 0.1
Loading...
Searching...
No Matches
internal_utils.h
Go to the documentation of this file.
1// uvco (c) 2023 Lewin Bormann. See LICENSE for specific terms.
2
3#pragma once
4
5#include <boost/assert.hpp>
6#include <fmt/core.h>
7#include <string_view>
8#include <uv.h>
9#include <uv/unix.h>
10
11#include <concepts>
12#include <cstddef>
13#include <string>
14#include <utility>
15
16namespace uvco {
17
20
22using uv_status = int;
23
24void allocator(uv_handle_t * /*unused*/, size_t sugg, uv_buf_t *buf);
25
26void freeUvBuf(const uv_buf_t *buf);
27
28// Checks if string_view is null-terminated. If it is, the fast path is taken.
29// Otherwise, a string is allocated which is null-terminated, and the function
30// is called with it.
31template <typename R, typename F>
32 requires std::is_invocable_r_v<R, F, std::string_view>
33R callWithNullTerminated(std::string_view view, F &&f) {
34 if (view.data()[view.size()] == '\0') {
35 return f(view.data());
36 }
37 std::string str(view);
38 return f(str.c_str());
39}
40
42template <typename Into, typename Handle> Into *getData(const Handle *handle) {
43 BOOST_ASSERT(handle != nullptr);
44 const void *data = uv_handle_get_data((const uv_handle_t *)handle);
45 BOOST_ASSERT(nullptr != data);
46 return (Into *)data;
47}
48
50template <typename Into, typename Handle>
51Into *getDataOrNull(const Handle *handle) {
52 BOOST_ASSERT(handle != nullptr);
53 const void *data = uv_handle_get_data((const uv_handle_t *)handle);
54 return (Into *)data;
55}
56
58template <typename Into, typename Request>
59Into *getRequestData(const Request *req) {
60 BOOST_ASSERT(req != nullptr);
61 const void *data = uv_req_get_data((const uv_req_t *)req);
62 BOOST_ASSERT(nullptr != data);
63 return (Into *)data;
64}
65
68template <typename Into, typename Request>
69Into *getRequestDataOrNull(const Request *req) {
70 BOOST_ASSERT(req != nullptr);
71 const void *data = uv_req_get_data((const uv_req_t *)req);
72 return (Into *)data;
73}
74
76template <typename Handle, typename Data>
77void setData(Handle *handle, Data *data) {
78 BOOST_ASSERT(handle != nullptr);
79 uv_handle_set_data((uv_handle_t *)handle, (void *)data);
80}
81
83template <typename Handle> void resetData(Handle *handle) {
84 BOOST_ASSERT(handle != nullptr);
85 uv_handle_set_data((uv_handle_t *)handle, nullptr);
86}
87
89template <typename Request, typename Data>
90void setRequestData(Request *req, Data *data) {
91 BOOST_ASSERT(req != nullptr);
92 uv_req_set_data((uv_req_t *)req, (void *)data);
93}
94
95template <typename Request> void resetRequestData(Request *req) {
96 BOOST_ASSERT(req != nullptr);
97 uv_req_set_data((uv_req_t *)req, (void *)nullptr);
98}
99
101template <typename Handle> bool dataIsNull(Handle *handle) {
102 BOOST_ASSERT(handle != nullptr);
103 return nullptr == uv_handle_get_data((const uv_handle_t *)handle);
104}
105
107template <typename Request> bool requestDataIsNull(Request *req) {
108 return nullptr == uv_req_get_data((const uv_req_t *)req);
109}
110
116 static void del(uv_handle_t *handle);
117 template <typename Handle> void operator()(Handle *handle) {
118 del((uv_handle_t *)handle);
119 }
120};
121
122extern const bool TRACK_LIFETIMES;
123
126template <typename T> class LifetimeTracker {
127public:
128 explicit LifetimeTracker(std::string name = "") : id_{std::move(name)} {
129 if (TRACK_LIFETIMES) {
130 fmt::print("ctor {}()#{}\n", typeid(T).name(), id_);
131 }
132 }
134 if (TRACK_LIFETIMES) {
135 fmt::print("ctor {}()#{}\n", typeid(T).name(), id_);
136 }
137 }
138 LifetimeTracker &operator=(LifetimeTracker && /*unused*/) noexcept {
139 if (TRACK_LIFETIMES) {
140 fmt::print("operator={}()#{}\n", typeid(T).name(), id_);
141 }
142 }
144 if (this == &other) {
145 return *this;
146 }
147 if (TRACK_LIFETIMES) {
148 fmt::print("operator={}({})#{}\n", typeid(T).name(), other.id_, id_);
149 }
150 id_ = fmt::format("{}/copy", other.id_);
151 }
153 : id_{fmt::format("{}/copy", other.id_)} {
154 if (TRACK_LIFETIMES) {
155 fmt::print("operator={}({})#{}\n", typeid(T).name(), other.id_, id_);
156 }
157 }
159 if (TRACK_LIFETIMES) {
160 fmt::print("dtor ~{}()\n", typeid(T).name());
161 }
162 }
163
164protected:
165 std::string id_;
166};
167
171public:
172 FlagGuard(const FlagGuard &) = delete;
173 FlagGuard(FlagGuard &&) = delete;
174 FlagGuard &operator=(const FlagGuard &) = delete;
176
178 explicit FlagGuard(bool &flag);
179 ~FlagGuard();
180
181private:
182 bool &flag_;
183};
184
185template <typename T> class ZeroAtExit {
186public:
187 explicit ZeroAtExit(T **pointer) : ptr_{pointer} {}
188 ZeroAtExit(const ZeroAtExit &) = delete;
189 ZeroAtExit(ZeroAtExit &&) = delete;
190 ZeroAtExit &operator=(const ZeroAtExit &) = delete;
193 if (ptr_ != nullptr) {
194 *ptr_ = nullptr;
195 }
196 }
197
198private:
199 T **ptr_ = nullptr;
200};
201
203
204} // namespace uvco
~FlagGuard()
Definition internal_utils.cc:91
FlagGuard(FlagGuard &&)=delete
FlagGuard & operator=(FlagGuard &&)=delete
FlagGuard & operator=(const FlagGuard &)=delete
FlagGuard(const FlagGuard &)=delete
bool & flag_
Definition internal_utils.h:182
LifetimeTracker(LifetimeTracker &&) noexcept
Definition internal_utils.h:133
LifetimeTracker(const LifetimeTracker< T > &other)
Definition internal_utils.h:152
LifetimeTracker< T > & operator=(const LifetimeTracker< T > &other)
Definition internal_utils.h:143
LifetimeTracker & operator=(LifetimeTracker &&) noexcept
Definition internal_utils.h:138
std::string id_
Definition internal_utils.h:165
~LifetimeTracker()
Definition internal_utils.h:158
LifetimeTracker(std::string name="")
Definition internal_utils.h:128
~ZeroAtExit()
Definition internal_utils.h:192
ZeroAtExit & operator=(ZeroAtExit &&)=delete
ZeroAtExit(const ZeroAtExit &)=delete
ZeroAtExit(T **pointer)
Definition internal_utils.h:187
ZeroAtExit & operator=(const ZeroAtExit &)=delete
T ** ptr_
Definition internal_utils.h:199
ZeroAtExit(ZeroAtExit &&)=delete
const bool TRACK_LIFETIMES
Definition internal_utils.cc:15
void setData(Handle *handle, Data *data)
Obtain data pointer set on request with type cast. Data may be nullptr.
Definition internal_utils.h:77
void resetRequestData(Request *req)
Definition internal_utils.h:95
bool requestDataIsNull(Request *req)
Check if request data is null.
Definition internal_utils.h:107
Into * getDataOrNull(const Handle *handle)
Definition internal_utils.h:51
Into * getRequestData(const Request *req)
Obtain data pointer set on request with nullptr check and type cast.
Definition internal_utils.h:59
Into * getData(const Handle *handle)
Obtain data pointer set on handle with nullptr check and type cast.
Definition internal_utils.h:42
void freeUvBuf(const uv_buf_t *buf)
Definition internal_utils.cc:26
void setRequestData(Request *req, Data *data)
Set data pointer on request.
Definition internal_utils.h:90
int uv_status
Result of a libuv operation, an errno error code.
Definition internal_utils.h:22
void allocator(uv_handle_t *, size_t sugg, uv_buf_t *buf)
libuv allocator.
Definition internal_utils.cc:18
bool dataIsNull(Handle *handle)
Check if handle data is null.
Definition internal_utils.h:101
R callWithNullTerminated(std::string_view view, F &&f)
Definition internal_utils.h:33
Into * getRequestDataOrNull(const Request *req)
Definition internal_utils.h:69
void resetData(Handle *handle)
Reset data pointer on handle to nullptr.
Definition internal_utils.h:83
Definition async_work.cc:18
Definition internal_utils.h:115
void operator()(Handle *handle)
Definition internal_utils.h:117
static void del(uv_handle_t *handle)
Definition internal_utils.cc:32