17 #if defined(__APPLE__)
18 #include <dispatch/dispatch.h>
19 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
22 #elif defined(_WIN32) || defined(_WIN64)
37 assert((
resources > 0) &&
"Semaphore resources counter must be greater than zero!");
39 #if defined(__APPLE__)
40 _semaphore = dispatch_semaphore_create(
resources);
41 if (_semaphore ==
nullptr)
42 throwex SystemException(
"Failed to initialize a semaphore!");
43 #elif defined(unix) || defined(__unix) || defined(__unix__)
44 int result = sem_init(&_semaphore, 0,
resources);
46 throwex SystemException(
"Failed to initialize a semaphore!");
47 #elif defined(_WIN32) || defined(_WIN64)
49 if (_semaphore ==
nullptr)
50 throwex SystemException(
"Failed to create a semaphore!");
56 #if defined(__APPLE__)
57 if (_semaphore !=
nullptr)
58 dispatch_release(_semaphore);
59 #elif defined(unix) || defined(__unix) || defined(__unix__)
60 int result = sem_destroy(&_semaphore);
62 fatality(SystemException(
"Failed to destroy a semaphore!"));
63 #elif defined(_WIN32) || defined(_WIN64)
64 if (!CloseHandle(_semaphore))
65 fatality(SystemException(
"Failed to close a semaphore!"));
76 #if defined(__APPLE__)
77 return (dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_NOW) == 0);
78 #elif defined(unix) || defined(__unix) || defined(__unix__)
79 int result = sem_trywait(&_semaphore);
80 if ((result != 0) && (errno != EAGAIN))
81 throwex SystemException(
"Failed to try lock a semaphore!");
83 #elif defined(_WIN32) || defined(_WIN64)
84 DWORD result = WaitForSingleObject(_semaphore, 0);
85 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
86 throwex SystemException(
"Failed to try lock a semaphore!");
87 return (result == WAIT_OBJECT_0);
95 #if defined(__APPLE__)
96 dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, timespan.nanoseconds());
97 return (dispatch_semaphore_wait(_semaphore, timeout) == 0);
98 #elif defined(unix) || defined(__unix) || defined(__unix__)
99 struct timespec timeout;
100 timeout.tv_sec = timespan.seconds();
101 timeout.tv_nsec = timespan.nanoseconds() % 1000000000;
102 int result = sem_timedwait(&_semaphore, &timeout);
103 if ((result != 0) && (errno != ETIMEDOUT))
104 throwex SystemException(
"Failed to try lock a semaphore for the given timeout!");
105 return (result == 0);
106 #elif defined(_WIN32) || defined(_WIN64)
107 DWORD result = WaitForSingleObject(_semaphore, std::max((DWORD)1, (DWORD)timespan.milliseconds()));
108 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
109 throwex SystemException(
"Failed to try lock a semaphore for the given timeout!");
110 return (result == WAIT_OBJECT_0);
116 #if defined(__APPLE__)
117 dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
118 #elif defined(unix) || defined(__unix) || defined(__unix__)
119 int result = sem_wait(&_semaphore);
121 throwex SystemException(
"Failed to lock a semaphore!");
122 #elif defined(_WIN32) || defined(_WIN64)
123 DWORD result = WaitForSingleObject(_semaphore, INFINITE);
124 if (result != WAIT_OBJECT_0)
125 throwex SystemException(
"Failed to lock a semaphore!");
131 #if defined(__APPLE__)
132 dispatch_semaphore_signal(_semaphore);
133 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
134 int result = sem_post(&_semaphore);
136 throwex SystemException(
"Failed to unlock a semaphore!");
137 #elif defined(_WIN32) || defined(_WIN64)
138 if (!ReleaseSemaphore(_semaphore, 1,
nullptr))
139 throwex SystemException(
"Failed to unlock a semaphore!");
145 #if defined(__APPLE__)
146 dispatch_semaphore_t _semaphore;
147 #elif defined(unix) || defined(__unix) || defined(__unix__)
149 #elif defined(_WIN32) || defined(_WIN64)
160 static_assert((StorageSize >=
sizeof(Impl)),
"Semaphore::StorageSize must be increased!");
161 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"Semaphore::StorageAlign must be adjusted!");
170 reinterpret_cast<Impl*
>(&_storage)->~Impl();
Semaphore(int resources)
Default class constructor.
bool TryLock()
Try to acquire semaphore without block.
bool TryLockFor(const Timespan ×pan)
Try to acquire semaphore for the given timespan.
int resources() const noexcept
Get the semaphore resources counter.
void Unlock()
Release semaphore.
void Lock()
Acquire semaphore with block.
Aligned storage validator.
#define throwex
Throw extended exception macro.
Fatal abort execution definition.
#define fatality(...)
Fatal abort execution extended macro.
C++ Common project definitions.
Semaphore synchronization primitive definition.
Aligned storage validator definition.