1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #define cmUVHandlePtr_cxx
4 #include "cmUVHandlePtr.h"
14 struct uv_loop_deleter
16 void operator()(uv_loop_t* loop) const;
19 void uv_loop_deleter::operator()(uv_loop_t* loop) const
21 uv_run(loop, UV_RUN_DEFAULT);
22 int result = uv_loop_close(loop);
28 int uv_loop_ptr::init(void* data)
32 this->loop.reset(static_cast<uv_loop_t*>(calloc(1, sizeof(uv_loop_t))),
34 this->loop->data = data;
36 return uv_loop_init(this->loop.get());
39 void uv_loop_ptr::reset()
44 uv_loop_ptr::operator uv_loop_t*()
46 return this->loop.get();
49 uv_loop_t* uv_loop_ptr::operator->() const noexcept
51 return this->loop.get();
54 uv_loop_t* uv_loop_ptr::get() const
56 return this->loop.get();
60 static void handle_default_delete(T* type_handle)
62 auto* handle = reinterpret_cast<uv_handle_t*>(type_handle);
64 assert(!uv_is_closing(handle));
65 if (!uv_is_closing(handle)) {
66 uv_close(handle, [](uv_handle_t* h) { free(h); });
72 * Encapsulates delete logic for a given handle type T
75 struct uv_handle_deleter
77 void operator()(T* type_handle) const { handle_default_delete(type_handle); }
81 void uv_handle_ptr_base_<T>::allocate(void* data)
86 We use calloc since we know all these types are c structs
87 and we just want to 0 init them. New would do the same thing;
88 but casting from uv_handle_t to certain other types -- namely
89 uv_timer_t -- triggers a cast_align warning on certain systems.
91 this->handle.reset(static_cast<T*>(calloc(1, sizeof(T))),
92 uv_handle_deleter<T>());
93 this->handle->data = data;
97 void uv_handle_ptr_base_<T>::reset()
102 template <typename T>
103 uv_handle_ptr_base_<T>::operator uv_handle_t*()
105 return reinterpret_cast<uv_handle_t*>(this->handle.get());
108 template <typename T>
109 T* uv_handle_ptr_base_<T>::operator->() const noexcept
111 return this->handle.get();
114 template <typename T>
115 T* uv_handle_ptr_base_<T>::get() const
117 return this->handle.get();
120 template <typename T>
121 uv_handle_ptr_<T>::operator T*() const
123 return this->handle.get();
126 #ifndef CMAKE_BOOTSTRAP
128 struct uv_handle_deleter<uv_async_t>
131 * While uv_async_send is itself thread-safe, there are
132 * no strong guarantees that close hasn't already been
133 * called on the handle; and that it might be deleted
134 * as the send call goes through. This mutex guards
137 * The shared_ptr here is to allow for copy construction
138 * which is mandated by the standard for Deleter on
141 std::shared_ptr<std::mutex> handleMutex;
144 : handleMutex(std::make_shared<std::mutex>())
148 void operator()(uv_async_t* handle)
150 std::lock_guard<std::mutex> lock(*this->handleMutex);
151 handle_default_delete(handle);
155 void uv_async_ptr::send()
158 std::get_deleter<uv_handle_deleter<uv_async_t>>(this->handle);
161 std::lock_guard<std::mutex> lock(*deleter->handleMutex);
163 uv_async_send(*this);
167 int uv_async_ptr::init(uv_loop_t& loop, uv_async_cb async_cb, void* data)
169 this->allocate(data);
170 return uv_async_init(&loop, this->handle.get(), async_cb);
175 struct uv_handle_deleter<uv_signal_t>
177 void operator()(uv_signal_t* handle) const
180 uv_signal_stop(handle);
181 handle_default_delete(handle);
186 int uv_signal_ptr::init(uv_loop_t& loop, void* data)
188 this->allocate(data);
189 return uv_signal_init(&loop, this->handle.get());
192 int uv_signal_ptr::start(uv_signal_cb cb, int signum)
194 assert(this->handle);
195 return uv_signal_start(*this, cb, signum);
198 void uv_signal_ptr::stop()
201 uv_signal_stop(*this);
205 int uv_pipe_ptr::init(uv_loop_t& loop, int ipc, void* data)
207 this->allocate(data);
208 return uv_pipe_init(&loop, *this, ipc);
211 uv_pipe_ptr::operator uv_stream_t*() const
213 return reinterpret_cast<uv_stream_t*>(this->handle.get());
216 int uv_process_ptr::spawn(uv_loop_t& loop, uv_process_options_t const& options,
219 this->allocate(data);
220 return uv_spawn(&loop, *this, &options);
223 int uv_timer_ptr::init(uv_loop_t& loop, void* data)
225 this->allocate(data);
226 return uv_timer_init(&loop, *this);
229 int uv_timer_ptr::start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
231 assert(this->handle);
232 return uv_timer_start(*this, cb, timeout, repeat);
235 #ifndef CMAKE_BOOTSTRAP
236 uv_tty_ptr::operator uv_stream_t*() const
238 return reinterpret_cast<uv_stream_t*>(this->handle.get());
241 int uv_tty_ptr::init(uv_loop_t& loop, int fd, int readable, void* data)
243 this->allocate(data);
244 return uv_tty_init(&loop, *this, fd, readable);
248 template class uv_handle_ptr_base_<uv_handle_t>;
250 #define UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(NAME) \
251 template class uv_handle_ptr_base_<uv_##NAME##_t>; \
252 template class uv_handle_ptr_<uv_##NAME##_t>;
254 UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(signal)
256 UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(pipe)
258 UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(stream)
260 UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(process)
262 UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(timer)
264 #ifndef CMAKE_BOOTSTRAP
265 UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async)
267 UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(tty)