37 #include "blocxx/BLOCXX_config.h"
48 #ifdef BLOCXX_HAVE_SYS_TIME_H
52 namespace BLOCXX_NAMESPACE
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);