barrier/mt/CCondVar.h

145 lines
2.9 KiB
C++

#ifndef CCONDVAR_H
#define CCONDVAR_H
#include "CMutex.h"
#include "BasicTypes.h"
class CStopwatch;
class CCondVarBase {
public:
// mutex must be supplied. all condition variables have an
// associated mutex. the copy c'tor uses the same mutex as the
// argument and is otherwise like the default c'tor.
CCondVarBase(CMutex* mutex);
~CCondVarBase();
// manipulators
// lock/unlock the mutex. see CMutex.
void lock() const;
void unlock() const;
// signal the condition. Signal() wakes one waiting thread.
// Broadcast() wakes all waiting threads.
void signal();
void broadcast();
// 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
CMutex* getMutex() const;
private:
void init();
void fini();
// not implemented
CCondVarBase(const CCondVarBase&);
CCondVarBase& operator=(const CCondVarBase&);
private:
CMutex* m_mutex;
void* m_cond;
#if defined(CONFIG_PLATFORM_WIN32)
enum { kSignal, kBroadcast };
mutable UInt32 m_waitCount;
CMutex m_waitCountMutex;
#endif
};
template <class T>
class CCondVar : public CCondVarBase {
public:
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.
operator const T&() const;
private:
T m_data;
};
template <class T>
inline
CCondVar<T>::CCondVar(CMutex* mutex, const T& data) :
CCondVarBase(mutex), m_data(data)
{
// do nothing
}
template <class T>
inline
CCondVar<T>::CCondVar(const CCondVar& cv) :
CCondVarBase(cv.getMutex()),
m_data(cv.m_data)
{
// do nothing
}
template <class T>
inline
CCondVar<T>::~CCondVar()
{
// do nothing
}
template <class T>
inline
CCondVar<T>& CCondVar<T>::operator=(const CCondVar<T>& cv)
{
m_data = cv.m_data;
return *this;
}
template <class T>
inline
CCondVar<T>& CCondVar<T>::operator=(const T& data)
{
m_data = data;
return *this;
}
template <class T>
inline
CCondVar<T>::operator const T&() const
{
return m_data;
}
// force instantiation of these common types
template class CCondVar<bool>;
template class CCondVar<SInt32>;
#endif