Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
semaphore.h
1#pragma once
2
3#include "gaia/config/config.h"
4
5#if GAIA_PLATFORM_WINDOWS
6 #include <windows.h>
7#elif GAIA_PLATFORM_APPLE
8 #include <TargetConditionals.h>
9 #include <dispatch/dispatch.h>
10 #include <pthread.h>
11#else
12 #include <pthread.h>
13 #include <semaphore.h>
14#endif
15
16namespace gaia {
17 namespace mt {
18 class GAIA_API Semaphore final {
19#if GAIA_PLATFORM_WINDOWS
20 void* m_handle;
21#elif GAIA_PLATFORM_APPLE
22 dispatch_semaphore_t m_handle;
23#else
24 sem_t m_handle;
25#endif
26
27 Semaphore(Semaphore&&) = delete;
28 Semaphore(const Semaphore&) = delete;
29 Semaphore& operator=(Semaphore&&) = delete;
30 Semaphore& operator=(const Semaphore&) = delete;
31
34 void init(int32_t count) {
35#if GAIA_PLATFORM_WINDOWS
36 m_handle = (void*)::CreateSemaphoreExW(NULL, count, INT_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS);
37 GAIA_ASSERT(m_handle != NULL);
38#elif GAIA_PLATFORM_APPLE
39 m_handle = dispatch_semaphore_create(count);
40 GAIA_ASSERT(m_handle != nullptr);
41#else
42 [[maybe_unused]] int ret = sem_init(&m_handle, 0, count);
43 GAIA_ASSERT(ret == 0);
44#endif
45 }
46
48 void done() {
49#if GAIA_PLATFORM_WINDOWS
50 if (m_handle != NULL) {
51 ::CloseHandle((HANDLE)m_handle);
52 m_handle = NULL;
53 }
54#elif GAIA_PLATFORM_APPLE
55 // NOTE: Dispatch objects are reference counted.
56 // They are automatically released when no longer used.
57 // -> dispatch_release(m_handle);
58#else
59 [[maybe_unused]] int ret = sem_destroy(&m_handle);
60 GAIA_ASSERT(ret == 0);
61#endif
62 }
63
64 public:
65 explicit Semaphore(int32_t count = 0) {
66 init(count);
67 }
68
69 ~Semaphore() {
70 done();
71 }
72
74 void release(int32_t count) {
75 GAIA_ASSERT(count > 0);
76
77#if GAIA_PLATFORM_WINDOWS
78 [[maybe_unused]] LONG prev = 0;
79 [[maybe_unused]] BOOL res = ::ReleaseSemaphore(m_handle, count, &prev);
80 GAIA_ASSERT(res != 0);
81#elif GAIA_PLATFORM_APPLE
82 do {
83 dispatch_semaphore_signal(m_handle);
84 } while ((--count) != 0);
85#else
86 do {
87 [[maybe_unused]] const auto ret = sem_post(&m_handle);
88 GAIA_ASSERT(ret == 0);
89 } while ((--count) != 0);
90#endif
91 }
92
96 bool wait() {
97#if GAIA_PLATFORM_WINDOWS
98 GAIA_ASSERT(m_handle != (void*)ERROR_INVALID_HANDLE);
99 DWORD ret = ::WaitForSingleObject(m_handle, INFINITE);
100 GAIA_ASSERT(ret == WAIT_OBJECT_0);
101 return (ret == WAIT_OBJECT_0);
102#elif GAIA_PLATFORM_APPLE
103 const auto res = dispatch_semaphore_wait(m_handle, DISPATCH_TIME_FOREVER);
104 GAIA_ASSERT(res == 0);
105 return (res == 0);
106#else
107 int res;
108 do {
109 res = sem_wait(&m_handle);
110 } while (res == -1 && errno == EINTR); // handle interrupts
111
112 GAIA_ASSERT(res == 0);
113 return (res == 0);
114#endif
115 }
116 };
117 } // namespace mt
118} // namespace gaia
Definition semaphore.h:18
void release(int32_t count)
Increments semaphore count by the specified amount.
Definition semaphore.h:74
bool wait()
Decrements semaphore count by 1. If the count is already 0, it waits indefinitely until semaphore cou...
Definition semaphore.h:96
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9