16 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
19 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
30 class NamedConditionVariable::Impl
33 Impl(
const std::string&
name) : _name(
name)
34 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
36 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
40 #if defined(__APPLE__)
41 throwex SystemException(
"Named condition variable is not supported!");
42 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
46 pthread_mutexattr_t mutex_attribute;
47 int result = pthread_mutexattr_init(&mutex_attribute);
49 throwex SystemException(
"Failed to initialize a mutex attribute for the named condition variable!", result);
50 result = pthread_mutexattr_setpshared(&mutex_attribute, PTHREAD_PROCESS_SHARED);
52 throwex SystemException(
"Failed to set a mutex process shared attribute for the named condition variable!", result);
53 result = pthread_mutex_init(&_shared->mutex, &mutex_attribute);
55 throwex SystemException(
"Failed to initialize a mutex for the named condition variable!", result);
56 result = pthread_mutexattr_destroy(&mutex_attribute);
58 throwex SystemException(
"Failed to destroy a mutex attribute for the named condition variable!", result);
60 pthread_condattr_t cond_attribute;
61 result = pthread_condattr_init(&cond_attribute);
63 throwex SystemException(
"Failed to initialize a conditional variable attribute for the named condition variable!", result);
64 result = pthread_condattr_setpshared(&cond_attribute, PTHREAD_PROCESS_SHARED);
66 throwex SystemException(
"Failed to set a conditional variable process shared attribute for the named condition variable!", result);
67 result = pthread_cond_init(&_shared->cond, &cond_attribute);
69 throwex SystemException(
"Failed to initialize a conditional variable for the named condition variable!", result);
70 result = pthread_condattr_destroy(&cond_attribute);
72 throwex SystemException(
"Failed to destroy a conditional variable attribute for the named condition variable!", result);
74 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
78 _mutex = CreateMutexA(
nullptr, FALSE, (
name +
"-mutex").c_str());
79 if (_mutex ==
nullptr)
80 throwex SystemException(
"Failed to create or open a named mutex for the named condition variable!");
81 _semaphore = CreateSemaphoreA(
nullptr, 0, std::numeric_limits<LONG>::max(), (
name +
"-semaphore").c_str());
82 if (_semaphore ==
nullptr)
83 throwex SystemException(
"Failed to create or open a named semaphore for the named condition variable!");
89 #if defined(__APPLE__)
90 fatality(SystemException(
"Named condition variable is not supported!"));
91 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
95 int result = pthread_mutex_destroy(&_shared->mutex);
97 fatality(SystemException(
"Failed to destroy a mutex for the named condition variable!", result));
98 result = pthread_cond_destroy(&_shared->cond);
100 fatality(SystemException(
"Failed to destroy a conditional variable for the named condition variable!", result));
102 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
103 if (!CloseHandle(_mutex))
104 fatality(SystemException(
"Failed to close a named mutex for the named condition variable!"));
105 if (!CloseHandle(_semaphore))
106 fatality(SystemException(
"Failed to close a named semaphore for the named condition variable!"));
110 const std::string&
name()
const
117 #if defined(__APPLE__)
118 throwex SystemException(
"Named condition variable is not supported!");
119 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
120 int result = pthread_cond_signal(&_shared->cond);
122 throwex SystemException(
"Failed to signal a named condition variable!", result);
123 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
125 DWORD result = WaitForSingleObject(_mutex, INFINITE);
126 if (result != WAIT_OBJECT_0)
127 throwex SystemException(
"Failed to lock a named mutex for the named condition variable!");
131 if (!ReleaseSemaphore(_semaphore, 1,
nullptr))
132 throwex SystemException(
"Failed to release one semaphore waiter for the named condition variable!");
134 if (!ReleaseMutex(_mutex))
135 throwex SystemException(
"Failed to unlock a named mutex for the named condition variable!");
141 #if defined(__APPLE__)
142 throwex SystemException(
"Named condition variable is not supported!");
143 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
144 int result = pthread_cond_broadcast(&_shared->cond);
146 throwex SystemException(
"Failed to broadcast a named condition variable!", result);
147 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
149 DWORD result = WaitForSingleObject(_mutex, INFINITE);
150 if (result != WAIT_OBJECT_0)
151 throwex SystemException(
"Failed to lock a named mutex for the named condition variable!");
153 if (!ReleaseSemaphore(_semaphore, *_shared,
nullptr))
154 throwex SystemException(
"Failed to release all semaphore waiters for the named condition variable!");
158 if (!ReleaseMutex(_mutex))
159 throwex SystemException(
"Failed to unlock a named mutex for the named condition variable!");
165 #if defined(__APPLE__)
166 throwex SystemException(
"Named condition variable is not supported!");
167 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
168 int result = pthread_cond_wait(&_shared->cond, &_shared->mutex);
170 throwex SystemException(
"Failed to waiting a named condition variable!", result);
171 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
173 DWORD result = WaitForSingleObject(_mutex, INFINITE);
174 if (result != WAIT_OBJECT_0)
175 throwex SystemException(
"Failed to lock a named mutex for the named condition variable!");
179 if (!ReleaseMutex(_mutex))
180 throwex SystemException(
"Failed to unlock a named mutex for the named condition variable!");
183 result = WaitForSingleObject(_semaphore, INFINITE);
184 if (result != WAIT_OBJECT_0)
185 throwex SystemException(
"Failed to wait a named condition variable!");
193 #if defined(__APPLE__)
194 throwex SystemException(
"Named condition variable is not supported!");
195 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
196 struct timespec timeout;
197 timeout.tv_sec = timespan.seconds();
198 timeout.tv_nsec = timespan.nanoseconds() % 1000000000;
199 int result = pthread_cond_timedwait(&_shared->cond, &_shared->mutex, &timeout);
200 if ((result != 0) && (result != ETIMEDOUT))
201 throwex SystemException(
"Failed to waiting a named condition variable for the given timeout!", result);
202 return (result == 0);
203 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
205 DWORD result = WaitForSingleObject(_mutex, INFINITE);
206 if (result != WAIT_OBJECT_0)
207 throwex SystemException(
"Failed to lock a named mutex for the named condition variable!");
211 if (!ReleaseMutex(_mutex))
212 throwex SystemException(
"Failed to unlock a named mutex for the named condition variable!");
215 result = WaitForSingleObject(_semaphore, std::max((DWORD)0, (DWORD)timespan.milliseconds()));
216 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
217 throwex SystemException(
"Failed to try lock a named condition variable for the given timeout!");
218 return (result == WAIT_OBJECT_0);
224 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
228 pthread_mutex_t mutex;
233 SharedType<CondVar> _shared;
234 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
237 SharedType<LONG> _shared;
247 static_assert((StorageSize >=
sizeof(Impl)),
"NamedConditionVariable::StorageSize must be increased!");
248 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"NamedConditionVariable::StorageAlign must be adjusted!");
251 new(&_storage)Impl(
name);
257 reinterpret_cast<Impl*
>(&_storage)->~Impl();
void NotifyOne()
Notify one of waiting thread about event occurred.
~NamedConditionVariable()
void NotifyAll()
Notify all waiting threads about event occurred.
NamedConditionVariable(const std::string &name)
Default class constructor.
const std::string & name() const
Get the condition variable name.
void Wait()
Wait until condition variable is notified.
bool TryWaitFor(const Timespan ×pan)
Try to wait for the given timespan until condition variable is notified.
Aligned storage validator.
#define throwex
Throw extended exception macro.
Fatal abort execution definition.
#define fatality(...)
Fatal abort execution extended macro.
Named condition variable synchronization primitive definition.
C++ Common project definitions.
Shared memory type definition.
Aligned storage validator definition.