37#include "blocxx/BLOCXX_config.h"
48#ifdef BLOCXX_HAVE_SYS_TIME_H
57#if defined(BLOCXX_USE_PTHREAD)
61 int res = pthread_cond_init(&
m_condition, PTHREAD_COND_ATTR_DEFAULT);
93 NonRecursiveMutexLockState
state;
94 mutex.conditionPreWait(
state);
96 mutex.conditionPostWait(
state);
97 assert(res == 0 || res == EINTR);
107 bool timespec_less(
struct timespec
const & x,
struct timespec
const & y)
109 return x.tv_sec < y.tv_sec ||
110 x.tv_sec == y.tv_sec && x.tv_nsec < y.tv_nsec;
114 int rc, pthread_cond_t * cond, pthread_mutex_t * mtx,
115 struct timespec
const * abstime
119 if (rc == -1 && errno == EAGAIN)
129 time_t
const max_future = 99999999;
130 time_t
const max_time = std::numeric_limits<time_t>::max();
132 struct timespec new_abstime;
133 new_abstime.tv_sec = (
134 now_sec <= max_time - max_future
135 ? now_sec + max_future
138 new_abstime.tv_nsec = 0;
139 bool early = timespec_less(new_abstime, *abstime);
142 new_abstime = *abstime;
144 int newrc = pthread_cond_timedwait(cond, mtx, &new_abstime);
145 return (newrc ==
ETIMEDOUT && early ? EINTR : newrc);
154 NonRecursiveMutexLockState
state;
155 mutex.conditionPreWait(
state);
159 TimeoutTimer timer(timeout);
161 res = pthread_cond_timedwait(&
m_condition,
state.pmutex, timer.asTimespec(ts));
163 mutex.conditionPostWait(
state);
164 assert(res == 0 || res ==
ETIMEDOUT || res == EINTR);
172#elif defined (BLOCXX_WIN32)
175 : m_condition(new ConditionInfo_t)
177 m_condition->waitersCount = 0;
178 m_condition->wasBroadcast =
false;
179 m_condition->queue = ::CreateSemaphore(
184 ::InitializeCriticalSection(&m_condition->waitersCountLock);
185 m_condition->waitersDone = ::CreateEvent(
195 ::DeleteCriticalSection(&
m_condition->waitersCountLock);
203 ::EnterCriticalSection(&
m_condition->waitersCountLock);
205 ::LeaveCriticalSection(&
m_condition->waitersCountLock);
217 ::EnterCriticalSection(&
m_condition->waitersCountLock);
218 bool haveWaiters =
false;
229 ::LeaveCriticalSection(&
m_condition->waitersCountLock);
232 ::WaitForSingleObject(
m_condition->waitersDone, INFINITE);
237 ::LeaveCriticalSection(&
m_condition->waitersCountLock);
253 NonRecursiveMutexLockState
state;
254 mutex.conditionPreWait(
state);
256 ::EnterCriticalSection(&
m_condition->waitersCountLock);
258 ::LeaveCriticalSection(&
m_condition->waitersCountLock);
260 TimeoutTimer timer(timeout);
263 if (::SignalObjectAndWait(mutex.m_mutex,
m_condition->queue, timer.asDWORDMs(),
264 false) == WAIT_TIMEOUT)
269 ::EnterCriticalSection(&
m_condition->waitersCountLock);
276 ::LeaveCriticalSection(&
m_condition->waitersCountLock);
284 ::SignalObjectAndWait(
m_condition->waitersDone, mutex.m_mutex,
290 ::WaitForSingleObject(mutex.m_mutex, INFINITE);
292 mutex.conditionPostWait(
state);
#define BLOCXX_DEFINE_EXCEPTION_WITH_ID(NAME)
Define a new exception class named <NAME>Exception that derives from Exception.
#define BLOCXX_THROW(exType, msg)
Throw an exception using FILE and LINE.
~Condition()
Destroy this Condition object.
void wait(NonRecursiveMutexLock &lock)
Atomically unlock a given mutex and wait for the this Condition object to get signalled.
void notifyAll()
Signal all threads that are currently waiting on the Condition object.
bool timedWait(NonRecursiveMutexLock &lock, const Timeout &timeout)
Atomically unlock a given mutex and wait for a given amount of time for this Condition object to get ...
Condition()
Construct a new Condition object.
bool doTimedWait(NonRecursiveMutex &mutex, const Timeout &timeout)
ConditionVar_t m_condition
void notifyOne()
Signal one thread that is currently waiting on the Condition object through the wait or timedWait met...
void doWait(NonRecursiveMutex &mutex)
static DateTime getCurrent()
Gets a DateTime instance set to the current system time.
Note that descriptions of what exceptions may be thrown assumes that object is used correctly,...
NonRecursiveMutex * m_mutex
A timeout can be absolute, which means that it will happen at the specified DateTime.
static Timeout relative(float seconds)
BLOCXX_COMMON_API void testCancel()
Test if this thread has been cancelled.