uvw  2.12.1
thread.h
1 #ifndef UVW_THREAD_INCLUDE_H
2 #define UVW_THREAD_INCLUDE_H
3 
4 #include <cstddef>
5 #include <cstdint>
6 #include <memory>
7 #include <string>
8 #include <type_traits>
9 #include <utility>
10 #include <uv.h>
11 #include "loop.h"
12 #include "underlying_type.hpp"
13 
14 namespace uvw {
15 
16 namespace details {
17 
18 enum class UVThreadCreateFlags : std::underlying_type_t<uv_thread_create_flags> {
19  THREAD_NO_FLAGS = UV_THREAD_NO_FLAGS,
20  THREAD_HAS_STACK_SIZE = UV_THREAD_HAS_STACK_SIZE
21 };
22 
23 }
24 
25 class Thread;
26 class ThreadLocalStorage;
27 class Once;
28 class Mutex;
29 class RWLock;
30 class Semaphore;
31 class Condition;
32 class Barrier;
33 
43 class Thread final: public UnderlyingType<Thread, uv_thread_t> {
44  using InternalTask = std::function<void(std::shared_ptr<void>)>;
45 
46  static void createCallback(void *arg);
47 
48 public:
49  using Options = details::UVThreadCreateFlags;
50  using Task = InternalTask;
51  using Type = uv_thread_t;
52 
53  explicit Thread(ConstructorAccess ca, std::shared_ptr<Loop> ref, Task t, std::shared_ptr<void> d = nullptr) noexcept;
54 
59  static Type self() noexcept;
60 
67  static bool equal(const Thread &tl, const Thread &tr) noexcept;
68 
69  ~Thread() noexcept;
70 
75  bool run() noexcept;
76 
90  bool run(Flags<Options> opts, std::size_t stack = {}) noexcept;
91 
96  bool join() noexcept;
97 
98 private:
99  std::shared_ptr<void> data;
100  Task task;
101 };
102 
110 class ThreadLocalStorage final: public UnderlyingType<ThreadLocalStorage, uv_key_t> {
111 public:
112  explicit ThreadLocalStorage(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept;
113 
114  ~ThreadLocalStorage() noexcept;
115 
121  template<typename T>
122  T *get() noexcept {
123  return static_cast<T *>(uv_key_get(UnderlyingType::get()));
124  }
125 
131  template<typename T>
132  void set(T *value) noexcept {
133  return uv_key_set(UnderlyingType::get(), value);
134  }
135 };
136 
143 class Once final: public UnderlyingType<Once, uv_once_t> {
144  static uv_once_t *guard() noexcept;
145 
146 public:
147  using UnderlyingType::UnderlyingType;
148 
158  template<typename F>
159  static void once(F &&f) noexcept {
160  using CallbackType = void (*)(void);
161  static_assert(std::is_convertible_v<F, CallbackType>);
162  CallbackType cb = f;
163  uv_once(guard(), cb);
164  }
165 };
166 
175 class Mutex final: public UnderlyingType<Mutex, uv_mutex_t> {
176  friend class Condition;
177 
178 public:
179  explicit Mutex(ConstructorAccess ca, std::shared_ptr<Loop> ref, bool recursive = false) noexcept;
180 
181  ~Mutex() noexcept;
182 
186  void lock() noexcept;
187 
192  bool tryLock() noexcept;
193 
197  void unlock() noexcept;
198 };
199 
203 class RWLock final: public UnderlyingType<RWLock, uv_rwlock_t> {
204 public:
205  explicit RWLock(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept;
206 
207  ~RWLock() noexcept;
208 
212  void rdLock() noexcept;
213 
218  bool tryRdLock() noexcept;
219 
223  void rdUnlock() noexcept;
224 
228  void wrLock() noexcept;
229 
234  bool tryWrLock() noexcept;
235 
239  void wrUnlock() noexcept;
240 };
241 
249 class Semaphore final: public UnderlyingType<Semaphore, uv_sem_t> {
250 public:
251  explicit Semaphore(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int value) noexcept;
252 
253  ~Semaphore() noexcept;
254 
258  void post() noexcept;
259 
263  void wait() noexcept;
264 
269  bool tryWait() noexcept;
270 };
271 
275 class Condition final: public UnderlyingType<Condition, uv_cond_t> {
276 public:
277  explicit Condition(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept;
278 
279  ~Condition() noexcept;
280 
287  void signal() noexcept;
288 
294  void broadcast() noexcept;
295 
305  void wait(Mutex &mutex) noexcept;
306 
322  bool timedWait(Mutex &mutex, uint64_t timeout) noexcept;
323 };
324 
334 class Barrier final: public UnderlyingType<Barrier, uv_barrier_t> {
335 public:
336  explicit Barrier(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int count) noexcept;
337 
338  ~Barrier() noexcept;
339 
344  bool wait() noexcept;
345 };
346 
347 } // namespace uvw
348 
349 #ifndef UVW_AS_LIB
350 # include "thread.cpp"
351 #endif
352 
353 #endif // UVW_THREAD_INCLUDE_H
The Barrier wrapper.
Definition: thread.h:334
bool wait() noexcept
Synchronizes at a barrier.
The Condition wrapper.
Definition: thread.h:275
void signal() noexcept
Signals a condition.
Utility class to handle flags.
Definition: util.h:80
The Mutex wrapper.
Definition: thread.h:175
void lock() noexcept
Locks the mutex.
The Once wrapper.
Definition: thread.h:143
static void once(F &&f) noexcept
Runs a function once and only once.
Definition: thread.h:159
The RWLock wrapper.
Definition: thread.h:203
void rdLock() noexcept
Locks a read-write lock object for reading.
The Semaphore wrapper.
Definition: thread.h:249
void post() noexcept
Unlocks a semaphore.
The ThreadLocalStorage wrapper.
Definition: thread.h:110
void set(T *value) noexcept
Sets the value of a given variable.
Definition: thread.h:132
T * get() noexcept
Gets the value of a given variable.
Definition: thread.h:122
The Thread wrapper.
Definition: thread.h:43
static bool equal(const Thread &tl, const Thread &tr) noexcept
Compares thread by means of their identifiers.
bool join() noexcept
Joins with a terminated thread.
bool run() noexcept
Creates a new thread.
Wrapper class for underlying types.
uvw default namespace.
Definition: async.h:8