uvw  2.10.0
thread.h
1 #ifndef UVW_THREAD_INCLUDE_H
2 #define UVW_THREAD_INCLUDE_H
3 
4 
5 #include <memory>
6 #include <string>
7 #include <cstddef>
8 #include <type_traits>
9 #include <utility>
10 #include <uv.h>
11 #include "loop.h"
12 #include "underlying_type.hpp"
13 
14 
15 namespace uvw {
16 
17 
18 namespace details {
19 
20 
21 enum class UVThreadCreateFlags: std::underlying_type_t<uv_thread_create_flags> {
22  THREAD_NO_FLAGS = UV_THREAD_NO_FLAGS,
23  THREAD_HAS_STACK_SIZE = UV_THREAD_HAS_STACK_SIZE
24 };
25 
26 
27 }
28 
29 
30 class Thread;
31 class ThreadLocalStorage;
32 class Once;
33 class Mutex;
34 class RWLock;
35 class Semaphore;
36 class Condition;
37 class Barrier;
38 
39 
49 class Thread final: public UnderlyingType<Thread, uv_thread_t> {
50  using InternalTask = std::function<void(std::shared_ptr<void>)>;
51 
52  static void createCallback(void *arg);
53 
54 public:
55  using Options = details::UVThreadCreateFlags;
56  using Task = InternalTask;
57  using Type = uv_thread_t;
58 
59  explicit Thread(ConstructorAccess ca, std::shared_ptr<Loop> ref, Task t, std::shared_ptr<void> d = nullptr) noexcept;
60 
65  static Type self() noexcept;
66 
73  static bool equal(const Thread &tl, const Thread &tr) noexcept;
74 
75  ~Thread() noexcept;
76 
81  bool run() noexcept;
82 
96  bool run(Flags<Options> opts, std::size_t stack = {}) noexcept;
97 
102  bool join() noexcept;
103 
104 private:
105  std::shared_ptr<void> data;
106  Task task;
107 };
108 
109 
117 class ThreadLocalStorage final: public UnderlyingType<ThreadLocalStorage, uv_key_t> {
118 public:
119  explicit ThreadLocalStorage(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept;
120 
121  ~ThreadLocalStorage() noexcept;
122 
128  template<typename T>
129  T* get() noexcept {
130  return static_cast<T*>(uv_key_get(UnderlyingType::get()));
131  }
132 
138  template<typename T>
139  void set(T *value) noexcept {
140  return uv_key_set(UnderlyingType::get(), value);
141  }
142 };
143 
144 
151 class Once final: public UnderlyingType<Once, uv_once_t> {
152  static uv_once_t* guard() noexcept;
153 
154 public:
155  using UnderlyingType::UnderlyingType;
156 
166  template<typename F>
167  static void once(F &&f) noexcept {
168  using CallbackType = void(*)(void);
169  static_assert(std::is_convertible_v<F, CallbackType>);
170  CallbackType cb = f;
171  uv_once(guard(), cb);
172  }
173 };
174 
175 
184 class Mutex final: public UnderlyingType<Mutex, uv_mutex_t> {
185  friend class Condition;
186 
187 public:
188  explicit Mutex(ConstructorAccess ca, std::shared_ptr<Loop> ref, bool recursive = false) noexcept;
189 
190  ~Mutex() noexcept;
191 
195  void lock() noexcept;
196 
201  bool tryLock() noexcept;
202 
206  void unlock() noexcept;
207 };
208 
209 
213 class RWLock final: public UnderlyingType<RWLock, uv_rwlock_t> {
214 public:
215  explicit RWLock(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept;
216 
217  ~RWLock() noexcept;
218 
222  void rdLock() noexcept;
223 
228  bool tryRdLock() noexcept;
229 
233  void rdUnlock() noexcept;
234 
238  void wrLock() noexcept;
239 
244  bool tryWrLock() noexcept;
245 
249  void wrUnlock() noexcept;
250 };
251 
252 
260 class Semaphore final: public UnderlyingType<Semaphore, uv_sem_t> {
261 public:
262  explicit Semaphore(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int value) noexcept;
263 
264  ~Semaphore() noexcept;
265 
269  void post() noexcept;
270 
274  void wait() noexcept;
275 
280  bool tryWait() noexcept;
281 };
282 
283 
287 class Condition final: public UnderlyingType<Condition, uv_cond_t> {
288 public:
289  explicit Condition(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept;
290 
291  ~Condition() noexcept;
292 
299  void signal() noexcept;
300 
306  void broadcast() noexcept;
307 
317  void wait(Mutex &mutex) noexcept;
318 
334  bool timedWait(Mutex &mutex, uint64_t timeout) noexcept;
335 };
336 
337 
347 class Barrier final: public UnderlyingType<Barrier, uv_barrier_t> {
348 public:
349  explicit Barrier(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int count) noexcept;
350 
351  ~Barrier() noexcept;
352 
357  bool wait() noexcept;
358 };
359 
360 
361 }
362 
363 
364 #ifndef UVW_AS_LIB
365 #include "thread.cpp"
366 #endif
367 
368 #endif // UVW_THREAD_INCLUDE_H
The Barrier wrapper.
Definition: thread.h:347
bool wait() noexcept
Synchronizes at a barrier.
The Condition wrapper.
Definition: thread.h:287
void signal() noexcept
Signals a condition.
Utility class to handle flags.
Definition: util.h:82
The Mutex wrapper.
Definition: thread.h:184
void lock() noexcept
Locks the mutex.
The Once wrapper.
Definition: thread.h:151
static void once(F &&f) noexcept
Runs a function once and only once.
Definition: thread.h:167
The RWLock wrapper.
Definition: thread.h:213
void rdLock() noexcept
Locks a read-write lock object for reading.
The Semaphore wrapper.
Definition: thread.h:260
void post() noexcept
Unlocks a semaphore.
The ThreadLocalStorage wrapper.
Definition: thread.h:117
void set(T *value) noexcept
Sets the value of a given variable.
Definition: thread.h:139
T * get() noexcept
Gets the value of a given variable.
Definition: thread.h:129
The Thread wrapper.
Definition: thread.h:49
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:10