WPILibC++  2018.4.1-20180819221726-1160-g6df500e
 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 { return uv_is_closing(m_uv_handle) != 0; }
108 
118  void Close() noexcept;
119 
126  void Reference() noexcept { uv_ref(m_uv_handle); }
127 
134  void Unreference() noexcept { uv_unref(m_uv_handle); }
135 
140  bool HasReference() const noexcept { return uv_has_ref(m_uv_handle) != 0; }
141 
146  size_t RawSize() const noexcept { return uv_handle_size(m_uv_handle->type); }
147 
153  uv_handle_t* GetRawHandle() const noexcept { return m_uv_handle; }
154 
170  void SetBufferAllocator(std::function<Buffer(size_t)> alloc,
171  std::function<void(Buffer&)> dealloc) {
172  m_allocBuf = alloc;
173  m_freeBuf = dealloc;
174  }
175 
182  void FreeBuf(Buffer& buf) const noexcept { m_freeBuf(buf); }
183 
188  template <typename T = void>
189  std::shared_ptr<T> GetData() const {
190  return std::static_pointer_cast<T>(m_data);
191  }
192 
197  void SetData(std::shared_ptr<void> data) { m_data = std::move(data); }
198 
203 
208 
213  void ReportError(int err) { error(Error(err)); }
214 
215  protected:
216  explicit Handle(uv_handle_t* uv_handle) : m_uv_handle{uv_handle} {
217  m_uv_handle->data = this;
218  }
219 
220  void Keep() noexcept { m_self = shared_from_this(); }
221  void Release() noexcept { m_self.reset(); }
222 
223  static void AllocBuf(uv_handle_t* handle, size_t size, uv_buf_t* buf);
224  static void DefaultFreeBuf(Buffer& buf);
225 
226  template <typename F, typename... Args>
227  bool Invoke(F&& f, Args&&... args) {
228  auto err = std::forward<F>(f)(std::forward<Args>(args)...);
229  if (err < 0) ReportError(err);
230  return err == 0;
231  }
232 
233  private:
234  std::shared_ptr<Handle> m_self;
235  uv_handle_t* m_uv_handle;
236  bool m_closed = false;
237  std::function<Buffer(size_t)> m_allocBuf{&Buffer::Allocate};
238  std::function<void(Buffer&)> m_freeBuf{&DefaultFreeBuf};
239  std::shared_ptr<void> m_data;
240 };
241 
245 template <typename T, typename U>
246 class HandleImpl : public Handle {
247  public:
248  std::shared_ptr<T> shared_from_this() {
249  return std::static_pointer_cast<T>(Handle::shared_from_this());
250  }
251 
252  std::shared_ptr<const T> shared_from_this() const {
253  return std::static_pointer_cast<const T>(Handle::shared_from_this());
254  }
255 
261  U* GetRaw() const noexcept {
262  return reinterpret_cast<U*>(this->GetRawHandle());
263  }
264 
265  protected:
266  HandleImpl() : Handle{reinterpret_cast<uv_handle_t*>(new U)} {}
267 };
268 
269 } // namespace uv
270 } // namespace wpi
271 
272 #endif // WPIUTIL_WPI_UV_HANDLE_H_
void FreeBuf(Buffer &buf) const noexcept
Free a buffer.
Definition: Handle.h:182
void Unreference() noexcept
Unreference the given handle.
Definition: Handle.h:134
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:261
std::shared_ptr< Loop > GetLoop() const noexcept
Get the loop where this handle runs.
Definition: Handle.h:65
Handle.
Definition: Handle.h:246
size_t RawSize() const noexcept
Return the size of the underlying handle type.
Definition: Handle.h:146
std::shared_ptr< T > GetData() const
Gets user-defined data.
Definition: Handle.h:189
void SetData(std::shared_ptr< void > data)
Sets user-defined data.
Definition: Handle.h:197
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:126
sig::Signal closed
Closed signal.
Definition: Handle.h:207
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:170
void ReportError(int err)
Report an error.
Definition: Handle.h:213
bool HasReference() const noexcept
Check if the given handle is referenced.
Definition: Handle.h:140
sig::Signal< Error > error
Error signal.
Definition: Handle.h:202
bool IsActive() const noexcept
Check if the handle is active.
Definition: Handle.h:97
Definition: uv.h:416
Event loop.
Definition: Loop.h:37
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:153