WPILibC++  2020.3.2
Handle.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #ifndef WPIUTIL_WPI_UV_HANDLE_H_
9 #define WPIUTIL_WPI_UV_HANDLE_H_
10 
11 #include <uv.h>
12 
13 #include <functional>
14 #include <memory>
15 #include <utility>
16 
17 #include "wpi/Signal.h"
18 #include "wpi/StringRef.h"
19 #include "wpi/uv/Buffer.h"
20 #include "wpi/uv/Error.h"
21 #include "wpi/uv/Loop.h"
22 
23 namespace wpi {
24 namespace uv {
25 
32 class Handle : public std::enable_shared_from_this<Handle> {
33  public:
34  using Type = uv_handle_type;
35 
36  Handle(const Handle&) = delete;
37  Handle(Handle&&) = delete;
38  Handle& operator=(const Handle&) = delete;
39  Handle& operator=(Handle&&) = delete;
40  virtual ~Handle() noexcept;
41 
51  Type GetType() const noexcept { return m_uv_handle->type; }
52 
56  StringRef GetTypeName() const noexcept {
57  return uv_handle_type_name(m_uv_handle->type);
58  }
59 
65  std::shared_ptr<Loop> GetLoop() const noexcept {
66  return GetLoopRef().shared_from_this();
67  }
68 
74  Loop& GetLoopRef() const noexcept {
75  return *static_cast<Loop*>(m_uv_handle->loop->data);
76  }
77 
97  bool IsActive() const noexcept { return uv_is_active(m_uv_handle) != 0; }
98 
107  bool IsClosing() const noexcept {
108  return m_closed || uv_is_closing(m_uv_handle) != 0;
109  }
110 
120  void Close() noexcept;
121 
131  void SetLoopClosing(bool loopClosing) noexcept {
132  m_loopClosing = loopClosing;
133  }
134 
143  bool IsLoopClosing() const noexcept { return m_loopClosing; }
144 
151  void Reference() noexcept { uv_ref(m_uv_handle); }
152 
159  void Unreference() noexcept { uv_unref(m_uv_handle); }
160 
165  bool HasReference() const noexcept { return uv_has_ref(m_uv_handle) != 0; }
166 
171  size_t RawSize() const noexcept { return uv_handle_size(m_uv_handle->type); }
172 
178  uv_handle_t* GetRawHandle() const noexcept { return m_uv_handle; }
179 
195  void SetBufferAllocator(std::function<Buffer(size_t)> alloc,
196  std::function<void(Buffer&)> dealloc) {
197  m_allocBuf = alloc;
198  m_freeBuf = dealloc;
199  }
200 
207  void FreeBuf(Buffer& buf) const noexcept { m_freeBuf(buf); }
208 
213  template <typename T = void>
214  std::shared_ptr<T> GetData() const {
215  return std::static_pointer_cast<T>(m_data);
216  }
217 
222  void SetData(std::shared_ptr<void> data) { m_data = std::move(data); }
223 
228 
233 
238  void ReportError(int err) const { error(Error(err)); }
239 
240  protected:
241  explicit Handle(uv_handle_t* uv_handle) : m_uv_handle{uv_handle} {
242  m_uv_handle->data = this;
243  }
244 
245  void Keep() noexcept { m_self = shared_from_this(); }
246  void Release() noexcept { m_self.reset(); }
247  void ForceClosed() noexcept { m_closed = true; }
248 
249  static void AllocBuf(uv_handle_t* handle, size_t size, uv_buf_t* buf);
250  static void DefaultFreeBuf(Buffer& buf);
251 
252  template <typename F, typename... Args>
253  bool Invoke(F&& f, Args&&... args) const {
254  auto err = std::forward<F>(f)(std::forward<Args>(args)...);
255  if (err < 0) ReportError(err);
256  return err == 0;
257  }
258 
259  private:
260  std::shared_ptr<Handle> m_self;
261  uv_handle_t* m_uv_handle;
262  bool m_closed = false;
263  bool m_loopClosing = false;
264  std::function<Buffer(size_t)> m_allocBuf{&Buffer::Allocate};
265  std::function<void(Buffer&)> m_freeBuf{&DefaultFreeBuf};
266  std::shared_ptr<void> m_data;
267 };
268 
272 template <typename T, typename U>
273 class HandleImpl : public Handle {
274  public:
275  std::shared_ptr<T> shared_from_this() {
276  return std::static_pointer_cast<T>(Handle::shared_from_this());
277  }
278 
279  std::shared_ptr<const T> shared_from_this() const {
280  return std::static_pointer_cast<const T>(Handle::shared_from_this());
281  }
282 
288  U* GetRaw() const noexcept {
289  return reinterpret_cast<U*>(this->GetRawHandle());
290  }
291 
292  protected:
293  HandleImpl() : Handle{reinterpret_cast<uv_handle_t*>(new U)} {}
294 };
295 
296 } // namespace uv
297 } // namespace wpi
298 
299 #endif // WPIUTIL_WPI_UV_HANDLE_H_
wpi::uv::Handle::GetData
std::shared_ptr< T > GetData() const
Gets user-defined data.
Definition: Handle.h:214
wpi::uv::HandleImpl::GetRaw
U * GetRaw() const noexcept
Get the underlying handle data structure.
Definition: Handle.h:288
wpi::uv::Handle::Unreference
void Unreference() noexcept
Unreference the given handle.
Definition: Handle.h:159
wpi::uv::Handle::FreeBuf
void FreeBuf(Buffer &buf) const noexcept
Free a buffer.
Definition: Handle.h:207
wpi::uv::Handle::SetBufferAllocator
void SetBufferAllocator(std::function< Buffer(size_t)> alloc, std::function< void(Buffer &)> dealloc)
Set the functions used for allocating and releasing buffers.
Definition: Handle.h:195
wpi::uv::Handle::HasReference
bool HasReference() const noexcept
Check if the given handle is referenced.
Definition: Handle.h:165
wpi::uv::Handle::IsLoopClosing
bool IsLoopClosing() const noexcept
Get the loop closing status.
Definition: Handle.h:143
wpi::uv::Handle::GetType
Type GetType() const noexcept
Get the type of the handle.
Definition: Handle.h:51
wpi::uv::Handle::GetRawHandle
uv_handle_t * GetRawHandle() const noexcept
Get the underlying handle data structure.
Definition: Handle.h:178
wpi::uv::Handle::GetLoop
std::shared_ptr< Loop > GetLoop() const noexcept
Get the loop where this handle runs.
Definition: Handle.h:65
wpi::uv::Buffer
Data buffer.
Definition: Buffer.h:27
wpi::uv::Handle
Handle.
Definition: Handle.h:32
wpi::uv::Handle::RawSize
size_t RawSize() const noexcept
Return the size of the underlying handle type.
Definition: Handle.h:171
wpi
WPILib C++ utilities (wpiutil) namespace.
Definition: EventLoopRunner.h:17
wpi::uv::Handle::closed
sig::Signal closed
Closed signal.
Definition: Handle.h:232
wpi::uv::Handle::ReportError
void ReportError(int err) const
Report an error.
Definition: Handle.h:238
wpi::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
wpi::uv::HandleImpl
Handle.
Definition: Handle.h:273
wpi::uv::Handle::error
sig::Signal< Error > error
Error signal.
Definition: Handle.h:227
wpi::uv::Handle::Close
void Close() noexcept
Request handle to be closed.
wpi::uv::Handle::SetLoopClosing
void SetLoopClosing(bool loopClosing) noexcept
Set if the loop is closing.
Definition: Handle.h:131
wpi::size
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1007
wpi::uv::Error
Error code.
Definition: Error.h:19
wpi::uv::Handle::Reference
void Reference() noexcept
Reference the given handle.
Definition: Handle.h:151
wpi::uv::Loop
Event loop.
Definition: Loop.h:39
wpi::uv::Handle::SetData
void SetData(std::shared_ptr< void > data)
Sets user-defined data.
Definition: Handle.h:222
wpi::uv::Handle::GetTypeName
StringRef GetTypeName() const noexcept
Get the name of the type of the handle.
Definition: Handle.h:56
wpi::uv::Handle::IsActive
bool IsActive() const noexcept
Check if the handle is active.
Definition: Handle.h:97
wpi::uv::Handle::IsClosing
bool IsClosing() const noexcept
Check if a handle is closing or closed.
Definition: Handle.h:107
wpi::uv::Handle::GetLoopRef
Loop & GetLoopRef() const noexcept
Get the loop where this handle runs.
Definition: Handle.h:74
wpi::sig::SignalBase
SignalBase is an implementation of the observer pattern, through the use of an emitting object and sl...
Definition: Signal.h:495