////////////////////////////////////////////////////////////////////////////////
//
// CThread - Convenient thread creation.
//
// Implements "has a thread" relationship, rather than the typical "is a thread" relationship.
//
// Pass object and member pointers or a function pointer rather than deriving from a Thread base
// and overriding ThreadMain.
//
// DOES NOT demonstrate error handling, portability or multithreaded programming.
//
// Dont forget multithreaded libs.
//
class CThread
{
////////////////////////////////////////////////////////////////////////////////
//
// implementation
//
private:
struct SThreadMain
{
CThread* m_Thread;
SThreadMain(CThread* Thread) : m_Thread(Thread)
{
}
virtual
~SThreadMain()
{
}
virtual
void Main() = 0;
};
struct SFnMain : public SThreadMain
{
typedef void (*_F)(CThread* Thread);
_F m_Fn;
SFnMain(CThread* Thread, _F Fn) : SThreadMain(Thread), m_Fn(Fn)
{
}
virtual
void Main()
{
CThread* thread = m_Thread;
_F fn = m_Fn;
delete this;
// can't access members anymore
(*fn)(thread);
thread->Ended();
}
};
template<class _C>
struct SClassMain : public SThreadMain
{
typedef void (_C::*_M)(CThread* Thread);
_C* m_Object;
_M m_Member;
SClassMain(CThread* Thread, _C* Object, _M Member) : SThreadMain(Thread), m_Object(Object), m_Member(Member)
{
}
virtual
void Main()
{
CThread* thread = m_Thread;
_C* object = m_Object;
_M member = m_Member;
delete this;
// can't access members anymore
(object->*member)(thread);
thread->Ended();
}
};
private:
static
void ThreadMain(void* Arg)
{
SThreadMain* main = (SThreadMain*)Arg;
main->Main();
}
private:
unsigned long m_hThread;
bool m_End;
////////////////////////////////////////////////////////////////////////////////
//
// constructors / destructors
//
public:
CThread() : m_hThread(0), m_End(false)
{
}
private:
CThread(const CThread& x);
private:
CThread& operator =(const CThread& x);
public:
~CThread()
{
if(Active())
{
RequestEnd();
Wait();
}
}
////////////////////////////////////////////////////////////////////////////////
//
// thread
//
public:
void BeginThread(void (*Fn)(CThread* Thread), int StackSize = 0)
{
SFnMain* main = new SFnMain(this, Fn);
unsigned long h_thread = _beginthread(ThreadMain, StackSize, main);
m_hThread = h_thread;
}
public:
template<class _C>
void BeginThread(_C* Object, void (_C::*Member)(CThread* Thread), int StackSize = 0)
{
SClassMain<_C>* main = new SClassMain<_C>(this, Object, Member);
unsigned long h_thread = _beginthread(ThreadMain, StackSize, main);
m_hThread = h_thread;
}
public:
unsigned long hThread() const
{
return m_hThread;
}
////////////////////////////////////////////////////////////////////////////////
//
// ipc
//
public:
void Ended()
{
m_hThread = 0;
m_End = false;
}
public:
void RequestEnd()
{
m_End = true;
}
public:
bool End() const
{
return m_End;
}
public:
bool Continue() const
{
return !End();
}
public:
bool Active() const
{
return m_hThread != 0;
}
public:
void Wait(int Milli = INFINITE) const
{
if(Active())
{
DWORD wait = WaitForSingleObject((HANDLE)m_hThread, Milli);
}
}
};
////////////////////////////////////////////////////////////////////////////////
|