1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
4 #include "cmConfigure.h" // IWYU pragma: keep
13 #if defined(__SUNPRO_CC)
17 # define CM_INHERIT_CTOR(Class, Base, Tpl) \
18 template <typename... Args> \
19 Class(Args&&... args) \
20 : Base Tpl(std::forward<Args>(args)...) \
26 # define CM_INHERIT_CTOR(Class, Base, Tpl) using Base Tpl ::Base
33 * RAII class to simplify and ensure the safe usage of uv_loop_t. This includes
34 * making sure resources are properly freed.
39 std::shared_ptr<uv_loop_t> loop;
42 uv_loop_ptr(uv_loop_ptr const&) = delete;
43 uv_loop_ptr& operator=(uv_loop_ptr const&) = delete;
44 uv_loop_ptr(uv_loop_ptr&&) noexcept;
45 uv_loop_ptr& operator=(uv_loop_ptr&&) noexcept;
47 // Dtor and ctor need to be inline defined like this for default ctors and
48 // dtors to work. Some compilers do not like '= default' here.
49 uv_loop_ptr() {} // NOLINT(modernize-use-equals-default)
50 uv_loop_ptr(std::nullptr_t) {}
51 ~uv_loop_ptr() { this->reset(); }
53 int init(void* data = nullptr);
56 * Properly close the handle if needed and sets the inner handle to nullptr
61 * Allow less verbose calling of uv_loop_* functions
62 * @return reinterpreted handle
64 operator uv_loop_t*();
66 uv_loop_t* get() const;
67 uv_loop_t* operator->() const noexcept;
71 * RAII class to simplify and ensure the safe usage of uv_*_t types. This
72 * includes making sure resources are properly freed and contains casting
73 * operators which allow for passing into relevant uv_* functions.
75 *@tparam T actual uv_*_t type represented.
78 class uv_handle_ptr_base_
82 friend class uv_handle_ptr_base_;
85 * This must be a pointer type since the handle can outlive this class.
86 * When uv_close is eventually called on the handle, the memory the
87 * handle inhabits must be valid until the close callback is called
88 * which can be later on in the loop.
90 std::shared_ptr<T> handle;
93 * Allocate memory for the type and optionally set it's 'data' pointer.
94 * Protected since this should only be called for an appropriate 'init'
97 * @param data data pointer to set
99 void allocate(void* data = nullptr);
102 uv_handle_ptr_base_(uv_handle_ptr_base_ const&) = delete;
103 uv_handle_ptr_base_& operator=(uv_handle_ptr_base_ const&) = delete;
104 uv_handle_ptr_base_(uv_handle_ptr_base_&&) noexcept;
105 uv_handle_ptr_base_& operator=(uv_handle_ptr_base_&&) noexcept;
108 * This move constructor allows us to move out of a more specialized
109 * uv type into a less specialized one. The only constraint is that
110 * the right hand side is castable to T.
112 * This allows you to return uv_handle_ptr or uv_stream_ptr from a function
113 * that initializes something like uv_pipe_ptr or uv_tcp_ptr and interact
114 * and clean up after it without caring about the exact type.
116 template <typename S,
117 typename = typename std::enable_if<
118 std::is_rvalue_reference<S&&>::value>::type>
119 uv_handle_ptr_base_(S&& rhs)
121 // This will force a compiler error if rhs doesn't have a casting
122 // operator to get T*
123 this->handle = std::shared_ptr<T>(rhs.handle, rhs);
127 // Dtor and ctor need to be inline defined like this for default ctors and
128 // dtors to work. Some compilers do not like '= default' here.
129 uv_handle_ptr_base_() {} // NOLINT(modernize-use-equals-default)
130 uv_handle_ptr_base_(std::nullptr_t) {}
131 ~uv_handle_ptr_base_() { this->reset(); }
134 * Properly close the handle if needed and sets the inner handle to nullptr
139 * Allow less verbose calling of uv_handle_* functions
140 * @return reinterpreted handle
142 operator uv_handle_t*();
145 T* operator->() const noexcept;
148 template <typename T>
149 inline uv_handle_ptr_base_<T>::uv_handle_ptr_base_(
150 uv_handle_ptr_base_<T>&&) noexcept = default;
151 template <typename T>
152 inline uv_handle_ptr_base_<T>& uv_handle_ptr_base_<T>::operator=(
153 uv_handle_ptr_base_<T>&&) noexcept = default;
156 * While uv_handle_ptr_base_ only exposes uv_handle_t*, this exposes uv_T_t*
157 * too. It is broken out like this so we can reuse most of the code for the
158 * uv_handle_ptr class.
160 template <typename T>
161 class uv_handle_ptr_ : public uv_handle_ptr_base_<T>
163 template <typename U>
164 friend class uv_handle_ptr_;
167 CM_INHERIT_CTOR(uv_handle_ptr_, uv_handle_ptr_base_, <T>);
170 * Allow less verbose calling of uv_<T> functions
171 * @return reinterpreted handle
177 * This specialization is required to avoid duplicate 'operator uv_handle_t*()'
181 class uv_handle_ptr_<uv_handle_t> : public uv_handle_ptr_base_<uv_handle_t>
184 CM_INHERIT_CTOR(uv_handle_ptr_, uv_handle_ptr_base_, <uv_handle_t>);
187 class uv_async_ptr : public uv_handle_ptr_<uv_async_t>
190 CM_INHERIT_CTOR(uv_async_ptr, uv_handle_ptr_, <uv_async_t>);
192 int init(uv_loop_t& loop, uv_async_cb async_cb, void* data = nullptr);
197 struct uv_signal_ptr : public uv_handle_ptr_<uv_signal_t>
199 CM_INHERIT_CTOR(uv_signal_ptr, uv_handle_ptr_, <uv_signal_t>);
201 int init(uv_loop_t& loop, void* data = nullptr);
203 int start(uv_signal_cb cb, int signum);
208 struct uv_pipe_ptr : public uv_handle_ptr_<uv_pipe_t>
210 CM_INHERIT_CTOR(uv_pipe_ptr, uv_handle_ptr_, <uv_pipe_t>);
212 operator uv_stream_t*() const;
214 int init(uv_loop_t& loop, int ipc, void* data = nullptr);
217 struct uv_process_ptr : public uv_handle_ptr_<uv_process_t>
219 CM_INHERIT_CTOR(uv_process_ptr, uv_handle_ptr_, <uv_process_t>);
221 int spawn(uv_loop_t& loop, uv_process_options_t const& options,
222 void* data = nullptr);
225 struct uv_timer_ptr : public uv_handle_ptr_<uv_timer_t>
227 CM_INHERIT_CTOR(uv_timer_ptr, uv_handle_ptr_, <uv_timer_t>);
229 int init(uv_loop_t& loop, void* data = nullptr);
231 int start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat);
234 struct uv_tty_ptr : public uv_handle_ptr_<uv_tty_t>
236 CM_INHERIT_CTOR(uv_tty_ptr, uv_handle_ptr_, <uv_tty_t>);
238 operator uv_stream_t*() const;
240 int init(uv_loop_t& loop, int fd, int readable, void* data = nullptr);
243 using uv_stream_ptr = uv_handle_ptr_<uv_stream_t>;
244 using uv_handle_ptr = uv_handle_ptr_<uv_handle_t>;
246 #ifndef cmUVHandlePtr_cxx
248 extern template class uv_handle_ptr_base_<uv_handle_t>;
250 # define UV_HANDLE_PTR_INSTANTIATE_EXTERN(NAME) \
251 extern template class uv_handle_ptr_base_<uv_##NAME##_t>; \
252 extern template class uv_handle_ptr_<uv_##NAME##_t>;
254 UV_HANDLE_PTR_INSTANTIATE_EXTERN(async)
256 UV_HANDLE_PTR_INSTANTIATE_EXTERN(signal)
258 UV_HANDLE_PTR_INSTANTIATE_EXTERN(pipe)
260 UV_HANDLE_PTR_INSTANTIATE_EXTERN(process)
262 UV_HANDLE_PTR_INSTANTIATE_EXTERN(stream)
264 UV_HANDLE_PTR_INSTANTIATE_EXTERN(timer)
266 UV_HANDLE_PTR_INSTANTIATE_EXTERN(tty)
268 # undef UV_HANDLE_PTR_INSTANTIATE_EXTERN