2001-10-06 18:13:28 +04:00
|
|
|
#ifndef CCONDVAR_H
|
|
|
|
#define CCONDVAR_H
|
|
|
|
|
|
|
|
#include "CMutex.h"
|
|
|
|
#include "BasicTypes.h"
|
|
|
|
|
|
|
|
class CStopwatch;
|
|
|
|
|
|
|
|
class CCondVarBase {
|
2002-04-29 18:40:01 +04:00
|
|
|
public:
|
2001-10-06 18:13:28 +04:00
|
|
|
// mutex must be supplied. all condition variables have an
|
2002-06-02 15:49:46 +04:00
|
|
|
// associated mutex.
|
2001-10-06 18:13:28 +04:00
|
|
|
CCondVarBase(CMutex* mutex);
|
|
|
|
~CCondVarBase();
|
|
|
|
|
|
|
|
// manipulators
|
|
|
|
|
|
|
|
// lock/unlock the mutex. see CMutex.
|
2001-10-14 20:58:01 +04:00
|
|
|
void lock() const;
|
|
|
|
void unlock() const;
|
2001-10-06 18:13:28 +04:00
|
|
|
|
|
|
|
// signal the condition. Signal() wakes one waiting thread.
|
|
|
|
// Broadcast() wakes all waiting threads.
|
2001-10-14 20:58:01 +04:00
|
|
|
void signal();
|
|
|
|
void broadcast();
|
2001-10-06 18:13:28 +04:00
|
|
|
|
|
|
|
// accessors
|
|
|
|
|
|
|
|
// wait on the condition. if timeout < 0 then wait until signalled,
|
|
|
|
// otherwise up to timeout seconds or until signalled, whichever
|
|
|
|
// comes first. since clients normally wait on condition variables
|
|
|
|
// in a loop, clients can provide a CStopwatch that acts as the
|
|
|
|
// timeout clock. using it, clients don't have to recalculate the
|
|
|
|
// timeout on each iteration. passing a stopwatch with a negative
|
|
|
|
// timeout is pointless but permitted.
|
|
|
|
//
|
|
|
|
// returns true if the object was signalled during the wait, false
|
|
|
|
// otherwise.
|
|
|
|
//
|
|
|
|
// (cancellation point)
|
|
|
|
bool wait(double timeout = -1.0) const;
|
|
|
|
bool wait(CStopwatch&, double timeout) const;
|
|
|
|
|
|
|
|
// get the mutex passed to the c'tor
|
2001-10-14 20:58:01 +04:00
|
|
|
CMutex* getMutex() const;
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
2001-10-06 18:13:28 +04:00
|
|
|
void init();
|
|
|
|
void fini();
|
|
|
|
|
|
|
|
// not implemented
|
|
|
|
CCondVarBase(const CCondVarBase&);
|
|
|
|
CCondVarBase& operator=(const CCondVarBase&);
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
2001-10-06 18:13:28 +04:00
|
|
|
CMutex* m_mutex;
|
|
|
|
void* m_cond;
|
|
|
|
|
2002-06-19 15:23:49 +04:00
|
|
|
#if WINDOWS_LIKE
|
2001-10-06 18:13:28 +04:00
|
|
|
enum { kSignal, kBroadcast };
|
|
|
|
mutable UInt32 m_waitCount;
|
|
|
|
CMutex m_waitCountMutex;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
class CCondVar : public CCondVarBase {
|
2002-04-29 18:40:01 +04:00
|
|
|
public:
|
2001-10-06 18:13:28 +04:00
|
|
|
CCondVar(CMutex* mutex, const T&);
|
|
|
|
CCondVar(const CCondVar&);
|
|
|
|
~CCondVar();
|
|
|
|
|
|
|
|
// manipulators
|
|
|
|
|
|
|
|
// assigns the value of the variable
|
|
|
|
CCondVar& operator=(const CCondVar&);
|
|
|
|
|
|
|
|
// assign the value
|
|
|
|
CCondVar& operator=(const T&);
|
|
|
|
|
|
|
|
// accessors
|
|
|
|
|
|
|
|
// get the const value. this object should be locked before
|
|
|
|
// calling this method.
|
2001-10-14 20:58:01 +04:00
|
|
|
operator const T&() const;
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
2001-10-06 18:13:28 +04:00
|
|
|
T m_data;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
inline
|
2002-06-11 02:06:45 +04:00
|
|
|
CCondVar<T>::CCondVar(
|
|
|
|
CMutex* mutex,
|
|
|
|
const T& data) :
|
|
|
|
CCondVarBase(mutex),
|
|
|
|
m_data(data)
|
2001-10-06 18:13:28 +04:00
|
|
|
{
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
inline
|
2002-06-11 02:06:45 +04:00
|
|
|
CCondVar<T>::CCondVar(
|
|
|
|
const CCondVar& cv) :
|
|
|
|
CCondVarBase(cv.getMutex()),
|
|
|
|
m_data(cv.m_data)
|
2001-10-06 18:13:28 +04:00
|
|
|
{
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
inline
|
|
|
|
CCondVar<T>::~CCondVar()
|
|
|
|
{
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
inline
|
2002-06-11 02:06:45 +04:00
|
|
|
CCondVar<T>&
|
|
|
|
CCondVar<T>::operator=(
|
|
|
|
const CCondVar<T>& cv)
|
2001-10-06 18:13:28 +04:00
|
|
|
{
|
|
|
|
m_data = cv.m_data;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
inline
|
2002-06-11 02:06:45 +04:00
|
|
|
CCondVar<T>&
|
|
|
|
CCondVar<T>::operator=(
|
|
|
|
const T& data)
|
2001-10-06 18:13:28 +04:00
|
|
|
{
|
|
|
|
m_data = data;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
inline
|
2001-10-14 20:58:01 +04:00
|
|
|
CCondVar<T>::operator const T&() const
|
2001-10-06 18:13:28 +04:00
|
|
|
{
|
|
|
|
return m_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// force instantiation of these common types
|
|
|
|
template class CCondVar<bool>;
|
|
|
|
template class CCondVar<SInt32>;
|
|
|
|
|
|
|
|
#endif
|