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);
95 res = pthread_cond_wait(&
m_condition, state.pmutex);
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));
162 res = check_timedwait(res, &
m_condition, state.pmutex, &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)
ConditionResourceException(const char *file, int line, const char *msg, int errorCode=::BLOCXX_NAMESPACE::Exception::UNKNOWN_ERROR_CODE, const Exception *otherException=0, int subClassId=::BLOCXX_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID)
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,...
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.