17 #if defined(__APPLE__)
20 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
23 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
34 class NamedSemaphore::Impl
39 assert((
resources > 0) &&
"Named semaphore resources counter must be greater than zero!");
41 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
44 _semaphore = sem_open(
name.c_str(), (O_CREAT | O_EXCL), 0666,
resources);
45 if (_semaphore == SEM_FAILED)
48 _semaphore = sem_open(
name.c_str(), O_CREAT, 0666,
resources);
49 if (_semaphore == SEM_FAILED)
50 throwex SystemException(
"Failed to initialize a named semaphore!");
54 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
56 if (_semaphore ==
nullptr)
57 throwex SystemException(
"Failed to create or open a named semaphore!");
63 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
64 int result = sem_close(_semaphore);
66 fatality(SystemException(
"Failed to close a named semaphore!"));
70 result = sem_unlink(_name.c_str());
72 fatality(SystemException(
"Failed to unlink a named semaphore!"));
74 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
75 if (!CloseHandle(_semaphore))
76 fatality(SystemException(
"Failed to close a named semaphore!"));
80 const std::string&
name()
const
92 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
93 int result = sem_trywait(_semaphore);
94 if ((result != 0) && (errno != EAGAIN))
95 throwex SystemException(
"Failed to try lock a named semaphore!");
97 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
98 DWORD result = WaitForSingleObject(_semaphore, 0);
99 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
100 throwex SystemException(
"Failed to try lock a named semaphore!");
101 return (result == WAIT_OBJECT_0);
109 #if defined(__APPLE__)
111 Timestamp finish = NanoTimestamp() + timespan;
119 while (NanoTimestamp() < finish)
130 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
131 struct timespec timeout;
132 timeout.tv_sec = timespan.seconds();
133 timeout.tv_nsec = timespan.nanoseconds() % 1000000000;
134 int result = sem_timedwait(_semaphore, &timeout);
135 if ((result != 0) && (errno != ETIMEDOUT))
136 throwex SystemException(
"Failed to try lock a named semaphore for the given timeout!");
137 return (result == 0);
138 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
139 DWORD result = WaitForSingleObject(_semaphore, std::max((DWORD)1, (DWORD)timespan.milliseconds()));
140 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
141 throwex SystemException(
"Failed to try lock a named semaphore for the given timeout!");
142 return (result == WAIT_OBJECT_0);
148 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
149 int result = sem_wait(_semaphore);
151 throwex SystemException(
"Failed to lock a named semaphore!");
152 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
153 DWORD result = WaitForSingleObject(_semaphore, INFINITE);
154 if (result != WAIT_OBJECT_0)
155 throwex SystemException(
"Failed to lock a named semaphore!");
161 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
162 int result = sem_post(_semaphore);
164 throwex SystemException(
"Failed to unlock a named semaphore!");
165 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
166 if (!ReleaseSemaphore(_semaphore, 1,
nullptr))
167 throwex SystemException(
"Failed to unlock a named semaphore!");
174 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
177 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
188 static_assert((StorageSize >=
sizeof(Impl)),
"NamedSemaphore::StorageSize must be increased!");
189 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"NamedSemaphore::StorageAlign must be adjusted!");
198 reinterpret_cast<Impl*
>(&_storage)->~Impl();
NamedSemaphore(const std::string &name, int resources)
Default class constructor.
int resources() const noexcept
Get the semaphore resources counter.
bool TryLockFor(const Timespan ×pan)
Try to acquire semaphore for the given timespan.
void Unlock()
Release semaphore.
const std::string & name() const
Get the semaphore name.
void Lock()
Acquire semaphore with block.
bool TryLock()
Try to acquire semaphore without block.
static void Yield() noexcept
Yield to other threads.
Aligned storage validator.
#define throwex
Throw extended exception macro.
Fatal abort execution definition.
#define fatality(...)
Fatal abort execution extended macro.
Named semaphore synchronization primitive definition.
C++ Common project definitions.
Semaphore synchronization primitive definition.
Aligned storage validator definition.