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);
void wait(NonRecursiveMutexLock &lock)
Atomically unlock a given mutex and wait for the this Condition object to get signalled.
~Condition()
Destroy this Condition object.
void notifyAll()
Signal all threads that are currently waiting on the Condition object.
#define BLOCXX_DEFINE_EXCEPTION_WITH_ID(NAME)
Define a new exception class named Exception that derives from Exception.
bool doTimedWait(NonRecursiveMutex &mutex, const Timeout &timeout)
BLOCXX_COMMON_API void testCancel()
Test if this thread has been cancelled.
static Timeout relative(float seconds)
void doWait(NonRecursiveMutex &mutex)
A timeout can be absolute, which means that it will happen at the specified DateTime.
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 ...
ConditionVar_t m_condition
Condition()
Construct a new Condition object.
#define BLOCXX_THROW(exType, msg)
Throw an exception using FILE and LINE.
static DateTime getCurrent()
Gets a DateTime instance set to the current system time.
NonRecursiveMutex * m_mutex
Note that descriptions of what exceptions may be thrown assumes that object is used correctly...
void notifyOne()
Signal one thread that is currently waiting on the Condition object through the wait or timedWait met...