WPILibC++  2019.1.1-beta-2-22-gc405188
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Handle.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2018 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 
128  void Reference() noexcept { uv_ref(m_uv_handle); }
129 
136  void Unreference() noexcept { uv_unref(m_uv_handle); }
137 
142  bool HasReference() const noexcept { return uv_has_ref(m_uv_handle) != 0; }
143 
148  size_t RawSize() const noexcept { return uv_handle_size(m_uv_handle->type); }
149 
155  uv_handle_t* GetRawHandle() const noexcept { return m_uv_handle; }
156 
172  void SetBufferAllocator(std::function<Buffer(size_t)> alloc,
173  std::function<void(Buffer&)> dealloc) {
174  m_allocBuf = alloc;
175  m_freeBuf = dealloc;
176  }
177 
184  void FreeBuf(Buffer& buf) const noexcept { m_freeBuf(buf); }
185 
190  template <typename T = void>
191  std::shared_ptr<T> GetData() const {
192  return std::static_pointer_cast<T>(m_data);
193  }
194 
199  void SetData(std::shared_ptr<void> data) { m_data = std::move(data); }
200 
205 
210 
215  void ReportError(int err) { error(Error(err)); }
216 
217  protected:
218  explicit Handle(uv_handle_t* uv_handle) : m_uv_handle{uv_handle} {
219  m_uv_handle->data = this;
220  }
221 
222  void Keep() noexcept { m_self = shared_from_this(); }
223  void Release() noexcept { m_self.reset(); }
224  void ForceClosed() noexcept { m_closed = true; }
225 
226  static void AllocBuf(uv_handle_t* handle, size_t size, uv_buf_t* buf);
227  static void DefaultFreeBuf(Buffer& buf);
228 
229  template <typename F, typename... Args>
230  bool Invoke(F&& f, Args&&... args) {
231  auto err = std::forward<F>(f)(std::forward<Args>(args)...);
232  if (err < 0) ReportError(err);
233  return err == 0;
234  }
235 
236  private:
237  std::shared_ptr<Handle> m_self;
238  uv_handle_t* m_uv_handle;
239  bool m_closed = false;
240  std::function<Buffer(size_t)> m_allocBuf{&Buffer::Allocate};
241  std::function<void(Buffer&)> m_freeBuf{&DefaultFreeBuf};
242  std::shared_ptr<void> m_data;
243 };
244 
248 template <typename T, typename U>
249 class HandleImpl : public Handle {
250  public:
251  std::shared_ptr<T> shared_from_this() {
252  return std::static_pointer_cast<T>(Handle::shared_from_this());
253  }
254 
255  std::shared_ptr<const T> shared_from_this() const {
256  return std::static_pointer_cast<const T>(Handle::shared_from_this());
257  }
258 
264  U* GetRaw() const noexcept {
265  return reinterpret_cast<U*>(this->GetRawHandle());
266  }
267 
268  protected:
269  HandleImpl() : Handle{reinterpret_cast<uv_handle_t*>(new U)} {}
270 };
271 
272 } // namespace uv
273 } // namespace wpi
274 
275 #endif // WPIUTIL_WPI_UV_HANDLE_H_
void FreeBuf(Buffer &buf) const noexcept
Free a buffer.
Definition: Handle.h:184
void Unreference() noexcept
Unreference the given handle.
Definition: Handle.h:136
Loop & GetLoopRef() const noexcept
Get the loop where this handle runs.
Definition: Handle.h:74
U * GetRaw() const noexcept
Get the underlying handle data structure.
Definition: Handle.h:264
std::shared_ptr< Loop > GetLoop() const noexcept
Get the loop where this handle runs.
Definition: Handle.h:65
Handle.
Definition: Handle.h:249
size_t RawSize() const noexcept
Return the size of the underlying handle type.
Definition: Handle.h:148
std::shared_ptr< T > GetData() const
Gets user-defined data.
Definition: Handle.h:191
void SetData(std::shared_ptr< void > data)
Sets user-defined data.
Definition: Handle.h:199
void Close() noexcept
Request handle to be closed.
Type GetType() const noexcept
Get the type of the handle.
Definition: Handle.h:51
WPILib C++ utilities (wpiutil) namespace.
Definition: SmallString.h:21
It should be possible to cast uv_buf_t[] to WSABUF[] see http://msdn.microsoft.com/en-us/library/ms74...
Definition: win.h:213
void Reference() noexcept
Reference the given handle.
Definition: Handle.h:128
sig::Signal closed
Closed signal.
Definition: Handle.h:209
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:172
void ReportError(int err)
Report an error.
Definition: Handle.h:215
bool HasReference() const noexcept
Check if the given handle is referenced.
Definition: Handle.h:142
sig::Signal< Error > error
Error signal.
Definition: Handle.h:204
bool IsActive() const noexcept
Check if the handle is active.
Definition: Handle.h:97
Definition: uv.h:416
Event loop.
Definition: Loop.h:39
StringRef GetTypeName() const noexcept
Get the name of the type of the handle.
Definition: Handle.h:56
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:999
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
bool IsClosing() const noexcept
Check if a handle is closing or closed.
Definition: Handle.h:107
Error code.
Definition: Error.h:19
Data buffer.
Definition: Buffer.h:27
SignalBase is an implementation of the observer pattern, through the use of an emitting object and sl...
Definition: Signal.h:495
Handle.
Definition: Handle.h:32
uv_handle_t * GetRawHandle() const noexcept
Get the underlying handle data structure.
Definition: Handle.h:155