25 thread_local
static std::atomic_int s_threadSignal{-1};
48 (*_waiters.front()) = 1;
57 for (
auto&& waiter : _waiters)
73 waitImpl(sync->getYieldHandle(), mutex, sync->signal());
76 template <
class PREDICATE>
83 template <
class PREDICATE>
88 waitImpl(sync->getYieldHandle(), mutex, predicate, sync->signal());
91 template <
class REP,
class PERIOD>
93 const std::chrono::duration<REP, PERIOD>& time)
98 template <
class REP,
class PERIOD>
101 const std::chrono::duration<REP, PERIOD>& time)
103 return waitForImpl(sync->getYieldHandle(), mutex, time, sync->signal());
106 template <
class REP,
class PERIOD,
class PREDICATE>
108 const std::chrono::duration<REP, PERIOD>& time,
111 return waitForImpl(
YieldingThread(), mutex, time, predicate, s_threadSignal);
114 template <
class REP,
class PERIOD,
class PREDICATE>
117 const std::chrono::duration<REP, PERIOD>& time,
120 return waitForImpl(sync->getYieldHandle(), mutex, time, predicate, sync->signal());
123 template <
class YIELDING>
124 void ConditionVariable::waitImpl(YIELDING&& yield,
126 std::atomic_int& signal)
135 _waiters.push_back(&signal);
139 while ((signal == 0) && !_destroyed)
146 template <
class YIELDING,
class PREDICATE>
147 void ConditionVariable::waitImpl(YIELDING&& yield,
150 std::atomic_int& signal)
152 while (!predicate() && !_destroyed)
154 waitImpl(std::forward<YIELDING>(yield), mutex, signal);
158 template <
class YIELDING,
class REP,
class PERIOD>
159 bool ConditionVariable::waitForImpl(YIELDING&& yield,
161 std::chrono::duration<REP, PERIOD>& time,
162 std::atomic_int& signal)
170 if (time == std::chrono::duration<REP, PERIOD>::zero())
175 _waiters.push_back(&signal);
179 auto start = std::chrono::high_resolution_clock::now();
180 auto elapsed = std::chrono::duration<REP, PERIOD>::zero();
181 bool timeout =
false;
184 while ((signal == 0) && !_destroyed)
187 elapsed = std::chrono::duration_cast<std::chrono::duration<REP, PERIOD>>(std::chrono::high_resolution_clock::now() - start);
198 time = timeout ? std::chrono::duration<REP, PERIOD>::zero() : time - elapsed;
202 template <
class YIELDING,
class REP,
class PERIOD,
class PREDICATE>
203 bool ConditionVariable::waitForImpl(YIELDING&& yield,
205 const std::chrono::duration<REP, PERIOD>& time,
207 std::atomic_int& signal)
209 if (time > std::chrono::duration<REP, PERIOD>(0)) {
210 auto duration = time;
211 while (!predicate() && !_destroyed)
213 if (!waitForImpl(std::forward<YIELDING>(yield), mutex, duration, signal))
void notifyOne()
Notify one waiting thread or coroutine.
Definition: quantum_condition_variable_impl.h:40
Definition: quantum_buffer_impl.h:22
void notifyAll()
Notify all waiting threads and coroutines.
Definition: quantum_condition_variable_impl.h:53
std::shared_ptr< ICoroSync > Ptr
Definition: quantum_icoro_sync.h:36
~ConditionVariable()
Destructor.
Definition: quantum_condition_variable_impl.h:33
YieldingThreadDuration< std::chrono::microseconds > YieldingThread
Definition: quantum_yielding_thread.h:57
Opposite form of RAII-style mechanism for mutex ownership. Releases a mutex on construction and acqui...
ConditionVariable()
Default constructor.
Definition: quantum_condition_variable_impl.h:28
RAII-style mechanism for mutex ownership. Acquires a mutex on construction and releases it inside the...
Definition: quantum_mutex.h:73
bool waitFor(Mutex &mutex, const std::chrono::duration< REP, PERIOD > &time)
Block the current thread until the condition is signalled via notifyOne() or notifyAll() or until 'ti...
Definition: quantum_condition_variable_impl.h:92
void wait(Mutex &mutex)
Block the current thread until the condition is signalled via notifyOne() or notifyAll().
Definition: quantum_condition_variable_impl.h:65