10 #include "underlying_type.hpp" 17 class ThreadLocalStorage;
26 class Thread final:
public UnderlyingType<Thread, uv_thread_t> {
27 using InternalTask = std::function<void(std::shared_ptr<void>)>;
29 static void createCallback(
void *arg) {
30 Thread &thread = *(
static_cast<Thread*
>(arg));
31 thread.task(thread.data);
35 using Task = InternalTask;
36 using Type = uv_thread_t;
38 explicit Thread(ConstructorAccess ca, std::shared_ptr<Loop> ref, InternalTask t, std::shared_ptr<void> d =
nullptr) noexcept
39 : UnderlyingType{ca, std::move(ref)}, data{std::move(d)}, task{std::move(t)}
42 static Type
self() noexcept {
43 return uv_thread_self();
46 static bool equal(
const Thread &tl,
const Thread &tr) noexcept {
47 return !(0 == uv_thread_equal(tl.get(), tr.get()));
55 return (0 == uv_thread_create(
get(), &createCallback,
this));
58 bool join() noexcept {
59 return (0 == uv_thread_join(
get()));
63 std::shared_ptr<void> data;
68 class ThreadLocalStorage final:
public UnderlyingType<ThreadLocalStorage, uv_key_t> {
70 explicit ThreadLocalStorage(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept
71 : UnderlyingType{ca, std::move(ref)}
73 uv_key_create(UnderlyingType::get());
76 ~ThreadLocalStorage() noexcept {
77 uv_key_delete(UnderlyingType::get());
82 return static_cast<T*
>(uv_key_get(UnderlyingType::get()));
86 void set(T *value) noexcept {
87 return uv_key_set(UnderlyingType::get(), value);
93 class Once final:
public UnderlyingType<Once, uv_once_t> {
94 static uv_once_t* guard() noexcept {
95 static uv_once_t once = UV_ONCE_INIT;
100 using UnderlyingType::UnderlyingType;
103 static void once(F &&f) noexcept {
104 using CallbackType = void (*)(void);
105 static_assert(std::is_convertible<F, CallbackType>::value,
"!");
107 uv_once(guard(), cb);
112 class Mutex final:
public UnderlyingType<Mutex, uv_mutex_t> {
113 friend class Condition;
116 explicit Mutex(ConstructorAccess ca, std::shared_ptr<Loop> ref,
bool recursive =
false) noexcept
117 : UnderlyingType{ca, std::move(ref)}
120 uv_mutex_init_recursive(
get());
122 uv_mutex_init(
get());
127 uv_mutex_destroy(
get());
130 void lock() noexcept {
131 uv_mutex_lock(
get());
134 bool tryLock() noexcept {
135 return (0 == uv_mutex_trylock(
get()));
138 void unlock() noexcept {
139 uv_mutex_unlock(
get());
144 class RWLock final:
public UnderlyingType<RWLock, uv_rwlock_t> {
146 explicit RWLock(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept
147 : UnderlyingType{ca, std::move(ref)}
149 uv_rwlock_init(
get());
153 uv_rwlock_destroy(
get());
156 void rdLock() noexcept {
157 uv_rwlock_rdlock(
get());
160 bool tryRdLock() noexcept {
161 return (0 == uv_rwlock_tryrdlock(
get()));
164 void rdUnlock() noexcept {
165 uv_rwlock_rdunlock(
get());
168 void wrLock() noexcept {
169 uv_rwlock_wrlock(
get());
172 bool tryWrLock() noexcept {
173 return (0 == uv_rwlock_trywrlock(
get()));
176 void wrUnlock() noexcept {
177 uv_rwlock_wrunlock(
get());
182 class Semaphore final:
public UnderlyingType<Semaphore, uv_sem_t> {
184 explicit Semaphore(ConstructorAccess ca, std::shared_ptr<Loop> ref,
unsigned int value) noexcept
185 : UnderlyingType{ca, std::move(ref)}
187 uv_sem_init(
get(), value);
190 ~Semaphore() noexcept {
191 uv_sem_destroy(
get());
194 void post() noexcept {
198 void wait() noexcept {
202 bool tryWait() noexcept {
203 return (0 == uv_sem_trywait(
get()));
208 class Condition final:
public UnderlyingType<Condition, uv_cond_t> {
210 explicit Condition(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept
211 : UnderlyingType{ca, std::move(ref)}
216 ~Condition() noexcept {
217 uv_cond_destroy(
get());
220 void signal() noexcept {
221 uv_cond_signal(
get());
224 void broadcast() noexcept {
225 uv_cond_broadcast(
get());
228 void wait(Mutex &mutex) noexcept {
229 uv_cond_wait(
get(), mutex.get());
232 bool timedWait(Mutex &mutex, uint64_t timeout) noexcept {
233 return (0 == uv_cond_timedwait(
get(), mutex.get(), timeout));
238 class Barrier final:
public UnderlyingType<Barrier, uv_barrier_t> {
240 explicit Barrier(ConstructorAccess ca, std::shared_ptr<Loop> ref,
unsigned int count) noexcept
241 : UnderlyingType{ca, std::move(ref)}
243 uv_barrier_init(
get(), count);
246 ~Barrier() noexcept {
247 uv_barrier_destroy(
get());
250 bool wait() noexcept {
251 return (0 == uv_barrier_wait(
get()));