6#if qExecution_WaitableEvent_SupportWaitForMultipleObjects
18 inline void WaitableEvent::WE_::Reset ()
27 inline bool WaitableEvent::WE_::GetIsSet () const noexcept
32 inline bool WaitableEvent::WE_::PeekIsSet () const noexcept
36 inline void WaitableEvent::WE_::Set ()
38 fConditionVariable.MutateDataNotifyAll ([
this] () { fTriggered =
true; });
46 inline WaitableEvent::WaitableEvent ()
50 inline void WaitableEvent::Reset ()
55 inline bool WaitableEvent::GetIsSet () const noexcept
57 return fWE_.GetIsSet ();
59 inline bool WaitableEvent::PeekIsSet () const noexcept
61 return fWE_.PeekIsSet ();
65 fWE_.WaitUntil (timeout + Time::GetTickCount ());
69 return fWE_.WaitUntilQuietly (timeout + Time::GetTickCount ());
73 fWE_.WaitUntil (timeoutAt);
77 return fWE_.WaitUntilQuietly (timeoutAt);
87 WaitUntil (timeoutAt);
91 inline auto WaitableEvent::WaitQuietlyAndReset (
const Time::Duration& timeout) -> WaitStatus
93 auto r = WaitQuietly (timeout);
100 auto r = WaitUntilQuietly (timeoutAt);
105#if qExecution_WaitableEvent_SupportWaitForMultipleObjects
106 template <
typename CONTAINER_OF_WAITABLE_EVENTS,
typename SET_OF_WAITABLE_EVENTS_RESULT>
107 inline SET_OF_WAITABLE_EVENTS_RESULT WaitableEvent::WaitForAny (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSeconds timeout)
109 return WaitForAnyUntil (waitableEvents, timeout + Time::GetTickCount ());
111 template <
typename ITERATOR_OF_WAITABLE_EVENTS,
typename SET_OF_WAITABLE_EVENTS_RESULT>
112 inline SET_OF_WAITABLE_EVENTS_RESULT WaitableEvent::WaitForAny (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart,
113 ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::DurationSeconds timeout)
115 return WaitForAnyUntil (waitableEventsStart, waitableEventsEnd, timeout + Time::GetTickCount ());
117 template <
typename CONTAINER_OF_WAITABLE_EVENTS,
typename SET_OF_WAITABLE_EVENTS_RESULT>
118 inline SET_OF_WAITABLE_EVENTS_RESULT WaitableEvent::WaitForAnyUntil (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::TimePointSeconds timeoutAt)
120 return WaitForAnyUntil (begin (waitableEvents), end (waitableEvents), timeoutAt);
122 template <
typename ITERATOR_OF_WAITABLE_EVENTS,
typename SET_OF_WAITABLE_EVENTS_RESULT>
123 SET_OF_WAITABLE_EVENTS_RESULT WaitableEvent::WaitForAnyUntil (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart,
124 ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd, Time::TimePointSeconds timeoutAt)
126 SET_OF_WAITABLE_EVENTS_RESULT result;
135 shared_ptr<WE_> we = make_shared<WE_> (eAutoReset);
136 [[maybe_unused]]
auto&& cleanup =
Finally ([we, waitableEventsStart, waitableEventsEnd] ()
noexcept {
137 Thread::SuppressInterruptionInContext suppressThreadInterrupts;
138 [[maybe_unused]]
auto&& critSec = lock_guard{sExtraWaitableEventsMutex_};
139 for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
140 (*i)->fExtraWaitableEvents_.remove (we);
144 [[maybe_unused]] lock_guard critSec{sExtraWaitableEventsMutex_};
145 for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
146 (*i)->fExtraWaitableEvents_.push_front (we);
149 while (result.empty ()) {
150 we->WaitUntil (timeoutAt);
151 for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
152 WaitableEvent* we2Test = *i;
153 if (we2Test->fWE_.PeekIsSet ()) {
154 if (we2Test->fWE_.fResetType == eAutoReset) {
155 we2Test->fWE_.Reset ();
157 result.insert (we2Test);
163 template <
typename CONTAINER_OF_WAITABLE_EVENTS>
164 inline void WaitableEvent::WaitForAll (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::DurationSeconds timeout)
166 WaitForAllUntil (waitableEvents, timeout + Time::GetTickCount ());
168 template <
typename ITERATOR_OF_WAITABLE_EVENTS>
169 inline void WaitableEvent::WaitForAll (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd,
170 Time::DurationSeconds timeout)
172 WaitForAllUntil (waitableEventsStart, waitableEventsEnd, timeout + Time::GetTickCount ());
174 template <
typename CONTAINER_OF_WAITABLE_EVENTS>
175 inline void WaitableEvent::WaitForAllUntil (CONTAINER_OF_WAITABLE_EVENTS waitableEvents, Time::TimePointSeconds timeoutAt)
177 WaitForAllUntil (begin (waitableEvents), end (waitableEvents), timeoutAt);
179 template <
typename ITERATOR_OF_WAITABLE_EVENTS>
180 void WaitableEvent::WaitForAllUntil (ITERATOR_OF_WAITABLE_EVENTS waitableEventsStart, ITERATOR_OF_WAITABLE_EVENTS waitableEventsEnd,
181 Time::TimePointSeconds timeoutAt)
191 shared_ptr<WE_> we = make_shared<WE_> (eAutoReset);
192 [[maybe_unused]]
auto&& cleanup =
Finally ([we, waitableEventsStart, waitableEventsEnd] ()
noexcept {
193 Thread::SuppressInterruptionInContext suppressThreadInterrupts;
194 [[maybe_unused]]
auto&& critSec = lock_guard{sExtraWaitableEventsMutex_};
195 for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
196 (*i)->fExtraWaitableEvents_.remove (we);
200 [[maybe_unused]] lock_guard critSec{sExtraWaitableEventsMutex_};
201 for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
202 (*i)->fExtraWaitableEvents_.push_front (we);
206 we->WaitUntil (timeoutAt);
207 bool anyStillWaiting =
false;
208 for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
209 WaitableEvent* we2Test = *i;
211 if (not we2Test->fWE_.PeekIsSet ()) {
212 anyStillWaiting =
true;
215 if (anyStillWaiting) {
219 for (ITERATOR_OF_WAITABLE_EVENTS i = waitableEventsStart; i != waitableEventsEnd; ++i) {
220 WaitableEvent* we2Test = *i;
222 if (we2Test->fWE_.fResetType == eAutoReset) {
223 Assert (we2Test->fWE_.PeekIsSet ());
224 we2Test->fWE_.Reset ();
235 DISABLE_COMPILER_MSC_WARNING_START (4996);
236 DISABLE_COMPILER_GCC_WARNING_START (
"GCC diagnostic ignored \"-Wdeprecated-declarations\"");
237 DISABLE_COMPILER_CLANG_WARNING_START (
"clang diagnostic ignored \"-Wdeprecated-declarations\"");
239 constexpr EnumNames<Execution::WaitableEvent::ResetType> DefaultNames<Execution::WaitableEvent::ResetType>::k{{{
240 {Execution::WaitableEvent::ResetType::eAutoReset, L
"AutoReset"},
241 {Execution::WaitableEvent::ResetType::eManualReset, L
"ManualReset"},
243 DISABLE_COMPILER_MSC_WARNING_END (4996);
244 DISABLE_COMPILER_GCC_WARNING_END (
"GCC diagnostic ignored \"-Wdeprecated-declarations\"");
245 DISABLE_COMPILER_CLANG_WARNING_END (
"clang diagnostic ignored \"-Wdeprecated-declarations\"");
247 constexpr EnumNames<Execution::WaitableEvent::WaitStatus> DefaultNames<Execution::WaitableEvent::WaitStatus>::k{{{
248 {Execution::WaitableEvent::WaitStatus::eTimeout, L
"Timeout"},
249 {Execution::WaitableEvent::WaitStatus::eTriggered, L
"Triggered"},
#define RequireNotNull(p)
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Duration is a chrono::duration<double> (=.
auto Finally(FUNCTION &&f) -> Private_::FinallySentry< FUNCTION >
lock_guard< MUTEX > QuickLockType