4#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
6#elif ORIGINAL_COMPILER_MSVC
75 template<
typename Pred>
87 template<
typename Pred>
127#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
172 void notify()
override;
178 void notifyAll()
override;
187#elif ORIGINAL_COMPILER_MSVC
188 class wCondition final :
public conditionBase
190 CONDITION_VARIABLE cond_;
195 explicit wCondition();
197 void wait(mutexBase& mutex)
override;
199 bool waitFor(mutexBase& mutex, time::duration d)
override;
201 void notify()
override;
203 void notifyAll()
override;
205 ~wCondition()
override;
210 #if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
212 #elif ORIGINAL_COMPILER_MSVC
232template<
typename Pred>
239template<
typename Pred>
265#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
266inline original::pCondition::pCondition() : cond_{}
274inline void original::pCondition::wait(mutexBase& mutex)
276 staticError<valueError, !std::is_same_v<mutex::native_handle, pMutex::native_handle>>::asserts();
278 const auto handle =
static_cast<mutex::native_handle*
>(mutex.nativeHandle());
279 if (
const int code = pthread_cond_wait(&this->cond_, handle); code != 0) {
280 throw sysError(
"Failed to wait on condition variable (pthread_cond_wait returned " +
printable::formatString(code) +
")");
284inline bool original::pCondition::waitFor(mutexBase& mutex,
const time::duration d)
286 staticError<valueError, !std::is_same_v<mutex::native_handle, pMutex::native_handle>>::asserts();
289 const auto ts = deadline.toTimespec();
290 const auto handle =
static_cast<mutex::native_handle*
>(mutex.nativeHandle());
291 const int code = pthread_cond_timedwait(&this->cond_, handle, &ts);
292 if (code == 0)
return true;
293 if (code == ETIMEDOUT)
return false;
294 throw sysError(
"Failed to timed wait on condition variable (pthread_cond_timed-wait returned " +
printable::formatString(code) +
")");
297inline void original::pCondition::notify()
299 if (
const int code = pthread_cond_signal(&this->cond_); code != 0) {
300 throw sysError(
"Failed to signal condition variable (pthread_cond_signal returned " +
printable::formatString(code) +
")");
304inline void original::pCondition::notifyAll()
306 if (
const int code = pthread_cond_broadcast(&this->cond_); code != 0) {
307 throw sysError(
"Failed to broadcast condition variable (pthread_cond_broadcast returned " +
printable::formatString(code) +
")");
311inline original::pCondition::~pCondition()
313 if (
const int code = pthread_cond_destroy(&this->cond_); code != 0) {
314 std::cerr <<
"Warning: Failed to destroy condition variable (pthread_cond_destroy returned "
315 << code <<
")" << std::endl;
318#elif ORIGINAL_COMPILER_MSVC
319inline original::wCondition::wCondition() : cond_{}
321 InitializeConditionVariable(&this->cond_);
324inline void original::wCondition::wait(mutexBase& mutex)
326 if (
const auto handle =
static_cast<mutex::native_handle*
>(mutex.nativeHandle());
327 !SleepConditionVariableSRW(&this->cond_, handle, INFINITE, 0)) {
328 throw sysError(
"Failed to wait on condition variable (SleepConditionVariableSRW returned error " +
333inline bool original::wCondition::waitFor(mutexBase& mutex,
const time::duration d)
335 const auto handle =
static_cast<mutex::native_handle*
>(mutex.nativeHandle());
336 if (
const auto timeout_ms = d.toDWMilliseconds();
337 !SleepConditionVariableSRW(&this->cond_, handle, timeout_ms, 0)) {
338 const DWORD error = GetLastError();
339 if (error == ERROR_TIMEOUT) {
342 throw sysError(
"Failed to timed wait on condition variable (SleepConditionVariableSRW returned error " +
348inline void original::wCondition::notify()
350 WakeConditionVariable(&this->cond_);
353inline void original::wCondition::notifyAll()
355 WakeAllConditionVariable(&this->cond_);
358inline original::wCondition::~wCondition() =
default;
361inline original::condition::condition() =
default;
365 this->cond_.wait(
mutex);
370 return this->cond_.waitFor(
mutex,
d);
375 this->cond_.notify();
380 this->cond_.notifyAll();
Abstract base class for condition variable implementations.
Definition condition.h:44
virtual void notifyAll()=0
Notifies all waiting threads.
conditionBase & operator=(const conditionBase &)=delete
Deleted copy assignment operator.
virtual void wait(mutexBase &mutex)=0
Waits for notification while holding the mutex.
conditionBase(const conditionBase &)=delete
Deleted copy constructor.
virtual bool waitFor(mutexBase &mutex, time::duration d)=0
Waits for notification with timeout.
void notifySome(u_integer n)
Notifies a specified number of waiting threads.
Definition condition.h:254
virtual ~conditionBase()=default
Virtual destructor.
conditionBase()=default
Default constructor.
virtual void notify()=0
Notifies one waiting thread.
Definition condition.h:209
void wait(mutexBase &mutex) override
Waits for notification while holding the mutex.
Definition condition.h:363
bool waitFor(mutexBase &mutex, time::duration d) override
Waits for notification with timeout.
Definition condition.h:368
void notifyAll() override
Notifies all waiting threads.
Definition condition.h:378
void notify() override
Notifies one waiting thread.
Definition condition.h:373
Abstract base class for mutex implementations.
Definition mutex.h:37
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
static std::string formatString(const TYPE &t)
Universal value-to-string conversion with type-specific formatting.
Definition printable.h:339
Exception for generic system failure.
Definition error.h:413
Represents a time duration with nanosecond precision.
Definition zeit.h:143
Represents a point in time with nanosecond precision.
Definition zeit.h:389
static point now()
Gets current time point.
Definition zeit.h:1386
Cross-platform mutex and lock management utilities.
Main namespace for the project Original.
Definition algorithms.h:21
Time and date handling utilities.