//------------------------ CSPThread.h: -----------------------

//*************************************************************
//*****       Copyright ©2002 - 2004 Micronovae Ltd       *****
//*****                All rights reserved                *****
//*************************************************************


#ifndef _CSPTHREAD
#define _CSPTHREAD

#include "CSPConf.h"
#include "CSPLib.h"
#include <process.h>


//---------------------- CSPThread -------------------------------

class CSPLIB_CLASS_EXPORT CSPThread : public CSPObject
{
public:

	CSPThread();
	virtual ~CSPThread();

	unsigned int GetID() const;
	unsigned long GetHandle() const;
	bool Start( void* pvUserParam = 0 );
	unsigned long Suspend();
	unsigned long Resume();
	bool SetPriority( int iLevel );
	int GetPriority() const;
	bool Kill( unsigned long ulExitCode = 0 );
	bool Wait( unsigned long ulTimeout = WAIT_FOREVER );
	unsigned long GetExitCode() const;

//	static bool CSPThread::WaitForThreads( unsigned long ulCount, ... );


	enum
	{
		ABOVE_NORMAL = THREAD_PRIORITY_ABOVE_NORMAL,
		BELOW_NORMAL = THREAD_PRIORITY_BELOW_NORMAL,
		HIGHEST = THREAD_PRIORITY_HIGHEST,
		IDLE = THREAD_PRIORITY_IDLE,
		LOWEST = THREAD_PRIORITY_LOWEST,
		NORMAL = THREAD_PRIORITY_NORMAL,
		TIME_CRITICAL = THREAD_PRIORITY_TIME_CRITICAL,
		ERROR_RETURN = THREAD_PRIORITY_ERROR_RETURN,
		WAIT_FOREVER = INFINITE
	};

protected:

	void* GetUserParam() const;
	virtual void Run() = 0;
	void SetExitCode( unsigned long ulExitCode );
	void SafeDestruction();
	

private:

	unsigned int uiThreadID;
	unsigned long ulThread;
	void* pvUserParameter;
	mutable int iPriorityLevel;
	unsigned long ulExitCode;
	bool bRunning;
	bool bKill;
	HANDLE hStart;
	HANDLE hEnd;

	CSPThread( const CSPThread& );
	CSPThread& operator = ( const CSPThread& );
	static unsigned int __stdcall ThreadProc( void* pCtx );
};


//---------------------- CSPThreadLockBase ---------------------------

class CSPLIB_CLASS_EXPORT CSPThreadLockBase : public CSPObject
{
public:
	CSPThreadLockBase();
	virtual ~CSPThreadLockBase();

	virtual unsigned long Lock() = 0;
	virtual unsigned long Unlock() = 0;
	virtual bool TryLock() = 0;
	unsigned long GetLockCount() const;

protected:
	unsigned long m_ulLockCount;

private:
	CSPThreadLockBase( CSPThreadLockBase& );
	CSPThreadLockBase& operator = ( CSPThreadLockBase& );
};


//---------------------- CSPThreadLock ---------------------------

class CSPLIB_CLASS_EXPORT CSPThreadLock : public CSPThreadLockBase
{
public:
	CSPThreadLock();
	virtual ~CSPThreadLock();

	unsigned long Lock();
	unsigned long Unlock();
	bool TryLock();

protected:
	CRITICAL_SECTION m_CS;

private:
	CSPThreadLock( CSPThreadLock& );
	CSPThreadLock& operator = ( CSPThreadLock& );
};

typedef CSPThreadLock CSPCriticalSection;



//---------------------- CSPThreadLockHandler ---------------------------

class CSPLIB_CLASS_EXPORT CSPThreadLockHandler : public CSPObject
{
public:
	CSPThreadLockHandler( CSPThreadLockBase& TL );
	virtual ~CSPThreadLockHandler();

	unsigned long Lock();
	unsigned long Unlock();
	bool TryLock();
	unsigned long GetLockCount() const;

protected:
	CSPThreadLockBase& CSPTL;
	unsigned long m_ulCount;
};


#endif
