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;
95 res = pthread_cond_wait(&
m_condition, state.pmutex);
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;
161 res = pthread_cond_timedwait(&
m_condition, state.pmutex, timer.asTimespec(ts));
162 res = check_timedwait(res, &
m_condition, state.pmutex, &ts);
164 assert(res == 0 || res ==
ETIMEDOUT || res == EINTR);
172 #elif defined (BLOCXX_WIN32) 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(
194 ::CloseHandle(m_condition->queue);
195 ::DeleteCriticalSection(&m_condition->waitersCountLock);
196 ::CloseHandle(m_condition->waitersDone);
203 ::EnterCriticalSection(&m_condition->waitersCountLock);
204 bool haveWaiters = m_condition->waitersCount > 0;
205 ::LeaveCriticalSection(&m_condition->waitersCountLock);
210 ::ReleaseSemaphore(m_condition->queue, 1, 0);
217 ::EnterCriticalSection(&m_condition->waitersCountLock);
218 bool haveWaiters =
false;
219 if (m_condition->waitersCount > 0)
222 haveWaiters = m_condition->wasBroadcast =
true;
228 ::ReleaseSemaphore(m_condition->queue, m_condition->waitersCount, 0);
229 ::LeaveCriticalSection(&m_condition->waitersCountLock);
232 ::WaitForSingleObject(m_condition->waitersDone, INFINITE);
233 m_condition->wasBroadcast =
false;
237 ::LeaveCriticalSection(&m_condition->waitersCountLock);
253 NonRecursiveMutexLockState
state;
256 ::EnterCriticalSection(&m_condition->waitersCountLock);
257 m_condition->waitersCount++;
258 ::LeaveCriticalSection(&m_condition->waitersCountLock);
263 if (::SignalObjectAndWait(mutex.
m_mutex, m_condition->queue, timer.asDWORDMs(),
264 false) == WAIT_TIMEOUT)
269 ::EnterCriticalSection(&m_condition->waitersCountLock);
270 m_condition->waitersCount--;
273 bool isLastWaiter = (m_condition->wasBroadcast && m_condition->waitersCount == 0
276 ::LeaveCriticalSection(&m_condition->waitersCountLock);
284 ::SignalObjectAndWait(m_condition->waitersDone, mutex.
m_mutex,
290 ::WaitForSingleObject(mutex.
m_mutex, INFINITE);
312 return timedWait(lock,
Timeout::relative(sTimeout + static_cast<float>(usTimeout) / 1000000.0));
323 return doTimedWait(*(lock.
m_mutex), timeout);
A TimeoutTimer is used by an algorithm to determine when a timeout has expired.
void conditionPreWait(NonRecursiveMutexLockState &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 <NAME>Exception that derives from Exception.
void conditionPostWait(NonRecursiveMutexLockState &state)
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
NonRecursiveMutex_t m_mutex
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...
void notifyOne()
Signal one thread that is currently waiting on the Condition object through the wait or timedWait met...