16 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
19 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
29 class NamedEventAutoReset::Impl
32 Impl(
const std::string&
name,
bool signaled) : _name(
name)
33 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
37 #if defined(__APPLE__)
38 throwex SystemException(
"Named auto-reset event is not supported!");
39 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
43 pthread_mutexattr_t mutex_attribute;
44 int result = pthread_mutexattr_init(&mutex_attribute);
46 throwex SystemException(
"Failed to initialize a mutex attribute for the named auto-reset event!", result);
47 result = pthread_mutexattr_setpshared(&mutex_attribute, PTHREAD_PROCESS_SHARED);
49 throwex SystemException(
"Failed to set a mutex process shared attribute for the named auto-reset event!", result);
50 result = pthread_mutex_init(&_shared->mutex, &mutex_attribute);
52 throwex SystemException(
"Failed to initialize a mutex for the named auto-reset event!", result);
53 result = pthread_mutexattr_destroy(&mutex_attribute);
55 throwex SystemException(
"Failed to destroy a mutex attribute for the named auto-reset event!", result);
57 pthread_condattr_t cond_attribute;
58 result = pthread_condattr_init(&cond_attribute);
60 throwex SystemException(
"Failed to initialize a conditional variable attribute for the named auto-reset event!", result);
61 result = pthread_condattr_setpshared(&cond_attribute, PTHREAD_PROCESS_SHARED);
63 throwex SystemException(
"Failed to set a conditional variable process shared attribute for the named auto-reset event!", result);
64 result = pthread_cond_init(&_shared->cond, &cond_attribute);
66 throwex SystemException(
"Failed to initialize a conditional variable for the named auto-reset event!", result);
67 result = pthread_condattr_destroy(&cond_attribute);
69 throwex SystemException(
"Failed to destroy a conditional variable attribute for the named auto-reset event!", result);
71 _shared->signaled = signaled ? 1 : 0;
73 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
74 _event = CreateEventA(
nullptr, FALSE, signaled ? TRUE : FALSE,
name.c_str());
75 if (_event ==
nullptr)
76 throwex SystemException(
"Failed to create or open a named auto-reset event!");
82 #if defined(__APPLE__)
83 fatality(SystemException(
"Named auto-reset event is not supported!"));
84 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
88 int result = pthread_mutex_destroy(&_shared->mutex);
90 fatality(SystemException(
"Failed to destroy a mutex for the named auto-reset event!", result));
91 result = pthread_cond_destroy(&_shared->cond);
93 fatality(SystemException(
"Failed to destroy a conditional variable for the named auto-reset event!", result));
95 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
96 if (!CloseHandle(_event))
97 fatality(SystemException(
"Failed to close a named auto-reset event!"));
101 const std::string&
name()
const
108 #if defined(__APPLE__)
109 throwex SystemException(
"Named auto-reset event is not supported!");
110 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
111 int result = pthread_mutex_lock(&_shared->mutex);
113 throwex SystemException(
"Failed to lock a mutex for the named auto-reset event!", result);
115 result = pthread_mutex_unlock(&_shared->mutex);
117 throwex SystemException(
"Failed to unlock a mutex for the named auto-reset event!", result);
118 result = pthread_cond_signal(&_shared->cond);
120 throwex SystemException(
"Failed to signal a named auto-reset event!", result);
121 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
122 if (!SetEvent(_event))
123 throwex SystemException(
"Failed to signal a named auto-reset event!");
129 #if defined(__APPLE__)
130 throwex SystemException(
"Named auto-reset event is not supported!");
131 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
132 int result = pthread_mutex_lock(&_shared->mutex);
134 throwex SystemException(
"Failed to lock a mutex for the named auto-reset event!", result);
135 bool signaled = (_shared->signaled-- > 0);
136 _shared->signaled = (_shared->signaled < 0) ? 0 : _shared->signaled;
137 result = pthread_mutex_unlock(&_shared->mutex);
139 throwex SystemException(
"Failed to unlock a mutex for the named auto-reset event!", result);
141 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
142 DWORD result = WaitForSingleObject(_event, 0);
143 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
144 throwex SystemException(
"Failed to try lock a named auto-reset event!");
145 return (result == WAIT_OBJECT_0);
153 #if defined(__APPLE__)
154 throwex SystemException(
"Named auto-reset event is not supported!");
155 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
156 struct timespec timeout;
157 timeout.tv_sec = timespan.seconds();
158 timeout.tv_nsec = timespan.nanoseconds() % 1000000000;
159 int result = pthread_mutex_lock(&_shared->mutex);
161 throwex SystemException(
"Failed to lock a mutex for the named auto-reset event!", result);
162 bool signaled =
true;
163 while (!_shared->signaled)
165 result = pthread_cond_timedwait(&_shared->cond, &_shared->mutex, &timeout);
166 if ((result != 0) && (result != ETIMEDOUT))
167 throwex SystemException(
"Failed to timeout waiting a conditional variable for the named auto-reset event!", result);
168 if (result == ETIMEDOUT)
169 signaled = (_shared->signaled > 0);
171 _shared->signaled = (_shared->signaled > 0) ? (_shared->signaled - 1) : 0;
172 result = pthread_mutex_unlock(&_shared->mutex);
174 throwex SystemException(
"Failed to unlock a mutex for the named auto-reset event!", result);
176 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
177 DWORD result = WaitForSingleObject(_event, std::max((DWORD)1, (DWORD)timespan.milliseconds()));
178 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
179 throwex SystemException(
"Failed to try lock a named auto-reset event for the given timeout!");
180 return (result == WAIT_OBJECT_0);
186 #if defined(__APPLE__)
187 throwex SystemException(
"Named auto-reset event is not supported!");
188 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
189 int result = pthread_mutex_lock(&_shared->mutex);
191 throwex SystemException(
"Failed to lock a mutex for the named auto-reset event!", result);
192 while (!_shared->signaled)
194 result = pthread_cond_wait(&_shared->cond, &_shared->mutex);
196 throwex SystemException(
"Failed to waiting a conditional variable for the named auto-reset event!", result);
198 _shared->signaled = (_shared->signaled > 0) ? (_shared->signaled - 1) : 0;
199 result = pthread_mutex_unlock(&_shared->mutex);
201 throwex SystemException(
"Failed to unlock a mutex for the named auto-reset event!", result);
202 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
203 DWORD result = WaitForSingleObject(_event, INFINITE);
204 if (result != WAIT_OBJECT_0)
205 throwex SystemException(
"Failed to lock a named auto-reset event!");
211 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
215 pthread_mutex_t mutex;
221 SharedType<EventHeader> _shared;
222 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
233 static_assert((StorageSize >=
sizeof(Impl)),
"NamedEventAutoReset::StorageSize must be increased!");
234 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"NamedEventAutoReset::StorageAlign must be adjusted!");
237 new(&_storage)Impl(
name, signaled);
243 reinterpret_cast<Impl*
>(&_storage)->~Impl();
const std::string & name() const
Get the event name.
void Wait()
Try to wait the event with block.
NamedEventAutoReset(const std::string &name, bool signaled=false)
Default class constructor.
void Signal()
Signal one of waiting thread about event occurred.
bool TryWait()
Try to wait the event without block.
bool TryWaitFor(const Timespan ×pan)
Try to wait the event for the given timespan.
Aligned storage validator.
#define throwex
Throw extended exception macro.
Fatal abort execution definition.
#define fatality(...)
Fatal abort execution extended macro.
Named auto-reset event synchronization primitive definition.
C++ Common project definitions.
Shared memory type definition.
Aligned storage validator definition.