﻿#ifndef _GTHREADBASE_ 
#define _GTHREADBASE_ 
#include <pthread.h> 
#include <sched.h> 
class GThreadBase
{
public:
	static const int THREAD_STOP_NOMAL = 0;
	static const int THREAD_STOP_JOIN = 1;
	static const int THREAD_STOP_TERM = 2;
	static const int THREAD_STOP_KILL = 3;
	
protected:
	static const int THREAD_PRIORITY_MAX = 5;
	static const int THREAD_PRIORITY_HIGH = 4;
	static const int THREAD_PRIORITY_MID = 3:
	static const int THREAD_PRIORITY_LOW = 2;
	static const int THREAD_PRIORITY_MIN = 1;
	static const int THREAD_PRIORITY_DEF = 1;
	static const int THREAD_POLICY_DEF = SCHED_OTHER;
	static const int THREAD_POLICY_FIFO = SCHED_FIFO;
	static const int THREAD_POLICY_RR = SCHED_RR;
	static const int THREAD_SCOPE_SYSTEM = PTHREAD_SCOPE_SYSTEM;
	static const int THREAD_SCOPE_PROCESS = PTHREAD_SCOPE_PROCESS;
	
	virtual ~GThreadBase(){} 
	virtual int StartThread(int _nInterval) = 0;
	
	virtual int StopThread(int _nMode) = 0;
	
	virtual int ActivCount(int &_nCount) = 0;
	
	virtual int ThreadCount(int &_nCount) = 0;
	
	virtual int CheckThread() = 0;
	
	virtual int GetMaxPriority(int &_nPriority) = 0;
	
	virtual int Join(void) = 0;
	
};

#endif 


#ifndef _THREAD_H_ 
#define _THREAD_H_ 
#include <pthread.h> 
#include <sched.h> 
#include <signal.h> 
#include <errno.h> 
#include "rt_sts.h" 
#define  THREAD_SUCCESS           RT_S_SUCCESS             
#define  THREAD_ERROR             RT_E_ERROR               
#define  THREAD_ALREADYACTIVE     -10                      
#define  THREAD_SIGNAL_INVALID    -21                      
#define  THREAD_NOT_FOUND         -22                      
#define  THREAD_DEADLOCK          -23                      
#define  THREAD_PRIORITY_MAX      5                        
#define  THREAD_PRIORITY_HIGH     4                        
#define  THREAD_PRIORITY_MID      3                        
#define  THREAD_PRIORITY_LOW      2                        
#define  THREAD_PRIORITY_MIN      1                        
#define  THREAD_PRIORITY_DEF      1                        
#define  THREAD_POLICY_DEF        SCHED_OTHER              
#define  THREAD_POLICY_FIFO       SCHED_FIFO               
#define  THREAD_POLICY_RE         SCHED_RR                 
#define  THREAD_SCOPE_SYSTEM      PTHREAD_SCOPE_SYSTEM     
#define  THREAD_SCOPE_PROCESS     PTHREAD_SCOPE_PROCESS    
extern "C" {
	void *_run_thread(void *_pObject);
} 

class Thread
{
public:
	Thread(
		int _nSetPriority = THREAD_PRIORITY_DEF,
		int _nSetPolicy = SCHED_OTHER,
		int _nSetScope = THREAD_SCOPE_SYSTEM 
	);
	
	virtual int StopLoop(void);
	virtual int StartThread(void);
	virtual int StopThread(void);
	virtual int SetPolicy(
		int _nSetPriority,
		int _nSetPolicy
	);
	static pthread_cond_t thread_condition;
	static pthread_mutex_t thread_cond_mutex;
	static int DeleteCoodition(void);
	int nPolicy;
	int nScope;
	struct sched_param oParam;
protected:
	virtual void* RunThread(void) = 0;
	friend void* _run_thread(void *_pObject);
	
	virtual int Join(void);
	bool bStartedFlg;
	bool bStopFlg;
	pthread_t nThreadID;
	
};

#endif


//---Thread. cpp 
#include "Thread. h" 
#include <string.h>
pthread_mutex_t Thread::thread_cond_mutex = PTHREADJUTEX_INITIALIZER;
pthread_cond_t Thread::thread_condition = PTHREAD_COND_INITIALIZER;
extern "C" void* _run_thread(
	void* _pObject
)
{
	if (_pObject == NULL){
		return(void*)(RT_E_ERROR);
		
	} 
	Thread *pThread = reinterpret_cast< Thread * >( _pObject);
	return pThread->RunThread();
	
}
Thread::Thread
(
	int _nSetPriority,
	int _nSetPolicy,
	int _nSetScope
)
{
	this->bStartedFlg = false;
	this->bStopFlg = false;
	this->nThreadID = 0;
	this->nPolicy = 0;
	this->nScope = 0;
	memset(&this->oParam, Ox00, sizeof(this->oParam));
	this->oParam.sched_priority = _nSetPriority;
	this->nPolicy = _nSetPolicy;
	this->nScope = _nSetScope;
	return;
	
} 

int Thread::StartThread(void)
{
	int nResult:
	pthread_attr_t oAttr;
	nResult = 0;
	memset(&oAttr, Ox00, sizeof(oAttr));
	pthread_attr_init(&oAttr);
	nResult = pthread_attr_setschedparam(&oAttr, &this->oParam);
	if (nResult 1 = 0)
	{
		return RT_E_ERROR;
	}
	nResult = pthread_attr_setschedpolicy(&oAttr, this->nPolicy);
	if (nResult != 0)
	{
		return RT_E_ERROR;
	}
	
	nResult = pthread_attr_setscope(&oAttr, this->nScope);
	if (nResult != 0)
	{
		return RT_E_ERROR;
	}
	
	if (this->bStartedFlg)
	{
		return RT_E_THREAD_ALREADY_ACTIVE;
	}
	
	this->nThreadlD = 0;
	nResult = pthread_create(&(this->nThreadlD), &oAttr, _run_thread, this);
	if (nResult != 0)
	{
		return RT_E_ERROR;
	}
	bStartedFlg = true;
	return RT_S_SUCCESS;
}
int Thread::StopLoop(void)
{
	this->bStopFlg = true;
	return RT_S_SUCCESS;
	
}
int Thread::StopThread(
	void 
)
{
	int nStatus;
	int nReturnStatus;
	nStatus = 0;
	nReturnStatus = RT_S_SUCCESS;
	nStatus = pthread_kill(this->nThreadID, SIGTERM);
	switch(nStatus)
	{
		case 0:
			nReturnStatus = RT_S_SUCCESS;
			break;
		case ESRCH:
			nReturnStatus = RT_E_THREAD_NOT_FOUND;
			break;
		default: 
			nReturnStatus = RT_E_ERROR;
			break;
	}
	return nReturnStatus: 
} 
int Thread::Join(void)
{
	int nStatus;
	int nReturnStatus;
	void * pThreadStatus;
	nStatus = 0;
	nReturnStatus = RT_S_SUCCESS;
	pThreadStatus = NULL;
	nStatus = pthread_join(this->nThreadID, &pThreadStatus);
	switch(nStatus)
	{
		case 0:
			nReturnStatus = RT_S_SUCCESS;
			break;
		case ESRCH:
			nReturnStatus = RT_E_THREAD_NOT_FOUND;
			break;
		case EDEADLK:
			nReturnStatus = RT_E_THREAD_DEADLOCK;
			break;
		default: 
			nReturnStatus = RT_E_ERROR;
			break;
	}
	return nReturnStatus;
}
int Thread::DeleteCondition(void)
{
	int nStatus;
	nStatus = 0;
	nStatus = pthread_mutex_destroy(&thread_cond_mutex);
	nStatus = pthread_cond_destroy(&thread_condition);
	return RT_S_SUCCESS;
}
int Thread::SetPolicy
( 
	int _nSetPriority,
	int nSetPolicy 
)
{
	int nStatus;
	nStatus = 0;
	this->oParam.sched_priority = _nSetPriority;
	this->nPolicy = _nSetPolicy;
	if (this->bStartedFlg == false)
	{
		return RT_S_SUCCESS;
	}
	if (this->bStopFlg == true)
	{
		return RT_S_SUCCESS;
	}
	nStatus = pthread_setschedparam(
		this->nThreadlD,
		this->nPolicy,
		&this->oParam);
	if (nStatus != 0)
	{
		return RT_E_ERROR;
	}
	return RT_S_SUCCESS;
}
#include "Thread. h" 
#include "d1j_rt_data.h" 
class JoinThread:public Thread
{
private:
protected:
	virtual void * RunThread(void);
public:
	JoinThread();
	virtual ~JoinThread(void);
	virtual int Init(void);
	virtual int JoinThreads();
};

#include "JoinThread. h" 
#include <string.h>
JoinThread:: JoinThread(
	void 
): Thread(THREAD_PRIORITY_MID, THREAD_POLICY_DEF)
{
}
JoinThread::~JoinThread(void 
)
{
	void * pStatus;
	pStatus = NULL;
	pthread_cond_broadcast(&( Thread::thread_condition));
	if (this->nThreadID != 0)
	{
		pthread_join(this->nThreadID, &pStatus);
	}
}
int JoinThread::Init(
	void
)
{
	int nStatus;
	nStatus = 0;
	nStatus = this->StartThread();
	ERR_RETURN(nStatus);
	return RT_S_SUCCESS;
} 

void * JoinThread::RunThread(
	void
)
{
	int nStatus;
	int nReturnStatus;
	nStatus = 0;
	nReturnStatus = RT_S_SUCCESS;
	nStatus = pthread_cond_wait(
		&(Thread::thread_condition),
		&(Thread::thread_cond_mutex)
	);
	if (nStatus != 0)
	{
		nReturnStatus = RT_E_ERROR;
	}
	return(void *)( nReturnStatus);
}
int JoinThread::JoinThreads(
	void
)
{
	int nStatus;
	nStatus = 0;
	nStatus = this->Join();
	this->nThreadID = 0;
	return RT_S_SUCCESS;
}
// ---GThread.h,GThread.cpp 
#ifndef _GTHREAD_ 
#define _GTHREAD_ 
#include <pthread.h> 
#include <sched.h> 
#include "rt_sts.h" 
#include "GThreadBase.h"
#include "Runnable.h"
extern "C" void* _runnable(void *_pObject);
class GThread:public GThreadBase
{
public:
	virtual int StartThread(int _nInterval);
	virtual int StopThread(int _nMode);
	virtual int Join();
	virtual int CheckThread();
	int ActivCount(int &_nCount)
	{
		_nCount += ( this->pObj->isRunning() == true ? 1 : 0);
		return RT_S_SUCCESS;
	}
	int ThreadCount(int &_nCount)
	{
		_nCount += 1;
		return RT_S_SUCCESS;
	} 
	int GetMaxPriority(int &_nPrioryty)
	{
		if (this->oParam.sched_priority > _nPrioryty)
		{
			_nPrioryty = this->oParam.sched_priority;
		}
		return RT_S_SUCCESS;
	}
protected:
	bool bRunning;
	pthread_t nThreadID;
	int nPolicy;
	int nScope;
	struct sched_param oParam;
	Runnable *pObj;
	GThread(Runnable *_pObject 
		, int _nSetPriority 
		, int _nSetPolicy 
		, int _nSetScope 
	);
	virtual ~GThread(){}
	virtual int KillThread(int nSignal);
	friend class GThreadGroup;
private:
	GThread(const GThread &_oCopy);
	GThread &operator = ( const GThread &_oCopy){ return *this; }
};
#endif 
#include "GThread.h" 
#include <string.h> 
#include <signal.h> 
#include <errno.h> 
#include <time.h>
extern "C" void* _runnable(
	void *_pObject
)
{ 
	void* pResult;
	pResult = NULL;
	if (_pObject == NULL)
	{
		return(void*)( RT_F_NULL_POINTER);
	}
	Runnable *pThread = reinterpret_cast< Runnable* >( _pObject);
	pThread->bRunning = true;
	pResult = pThread->RunThread();
	pThread->bRunning = false;
	return pResult;
}
GThread:: GThread
( 
	Runnable *_pObject 
	, int _nSetPriority 
	, int _nSetPolicy
	, int _nSetScope 
):p0bj(_pObject), nPolicy(_nSetPolicy), nScope(_nSetScope)
{
	
	memset(&this->oParam, 0x00, sizeof(this->oParam));
	this->oParam.sched_priority = _nSetPriority;
#ifdef FOR_DBPS
	this->nThreadID = -1 ;
#endif
	return;
}
int GThread::StartThread(
	int _nInterval 
)
{
	int nStatus;
	pthread_attr_t oAttr;
	struct timespec oTime;
	nStatus = 0;
	memset(&oAttr, Ox00, sizeof(oAttr));
	memset(&oTime, 0x00, sizeof(oTime));
	if (this->pObj->isRunning() == true)
	{
		return RT_S_SUCCESS;
		1}
#ifdef FOR_DBPS
	if( this->nThreadID != -1) {
	pthread_join( this->nThreadlD, NULL );
	pthread_attr_destroy( &oAttr ) ;
	}
#endif
	pthread_attr_init(&oAttr);
	nStatus = pthread_attr_setschedparam(&oAttr, &this->oParam);
	if (nStatus != 0)
	{
		return RT_E_ERROR;
	}
	nStatus = pthread_attr_setschedpolicy(&oAttr, this->nPolicy);
	if (nStatus != 0)
	{
		return RT_E_ERROR;
	}
	nStatus = pthread_attr_setscope(&oAttr, this->nScope);
	if (nStatus != 0)
	{
		return RT_E_ERROR;
	}
	nStatus = this->pObj->StartLoop();
	ERR_RETURN(nStatus);
#ifdef FOR_DBPS 
	this->p0bj->bRunning = true ;
#endif 
	nStatus = pthread_create(
		&( this->nThreadID)
		, &oAttr, _runnable 
		, this->pObj 
	);
	if (nStatus != 0)
	{
		return RT_E_ERROR;
	}
	if (_nInterval <= 0)
	{
		return RT_S_SUCCESS;
	}
	while (this->pObj->isRunning() == false)
	{
		oTime.tv_sec = _nInterval / 1000;
		oTime.tv_nsec = ( _nInterval % 1000)* 1000 * 1000;
		nanosleep(&oTime, NULL);
	}
	return RT_S_SUCCESS;
}
int GThread::StopThread(
	int _nMode
)
{
	int nStatus;
	nStatus = 0;
	if (this->pObj->isRunning() == false)
	{
		return RT_S_SUCCESS;
	}
	switch(_nMode)
	{
		case THREAD_STOP_NOMAL:
			nStatus = this->pObj->StopLoop();
			ERR_RETURN(nStatus);
			break;
		case THREAD_STOP_JOIN:
			nStatus = this->pObj->StopLoop();
			ERR_RETURN(nStatus);
			nStatus = this->join();
			ERR_RETURN(nStatus);
			break;
		case THREAD_STOP_TERM:
			nStatus = this->KillThread(SIGTERM);
			ERR_RETURN(nStatus);
			this->pObj->ClearFlag();
			break;
		case THREAD_STOP_KILL:
			nStatus = this->KillThread(SIGKILL);
			ERR_RETURN(nStatus);
			this->pObj->ClearFlag();
			break;
		default:
			return RT_E_INVAL;
	}
	return RT_S_SUCCESS;
}
int GThread::KillThread(
	int nSignal 
)
{
	int nStatus;
	int nResult;
	nStatus = 0;
	nResult = 0;
	nResult = pthread_kill(this->nThreadID, nSignal);
	switch(nResult)
	{
		case 0:
			nStatus = RT_S_SUCCESS;
			break;
		case ESRCH:
			nStatus = RT_E_THREAD_NOT_FOUND;
			break;
		default:
			nStatus = RT_E_ERROR;
			break;
	}
	return nStatus;
}
int GThread::Join(
	void 
)
{
	int nStatus;
	int nResult;
	void* pThreadStatus;
	nStatus = 0;
	nResult = 0;
	pThreadStatus = NULL;
	if (this->pObj->isRunning() == false)
	{
		return RT_S_SUCCESS;
	}
	nResult = pthread_join(this->nThreadID, &ThreadStatus);
	switch(nResult)
	{
		case 0:
			nStatus = RT_S_SUCCESS;
			break;
		case ESRCH:
			nStatus = RT_E_THREAD_NOT_FOUND;
			break;
		case EDEADLK:
			nStatus = RT_E_THREAD_DEADLOCK;
			break;
		default:
			nStatus = RT_E_ERROR;
			break;
	}
	return nStatus;
}
int GThread::CheckThread(
	void 
)
{
	int nStatus;
	static const char *sMsg = "ThreadStatusError!!VtStatus[%d]";
	nStatus = 0;
	if (this->pObj->isRunning() == false)
	{
		return RT_S_SUCCESS;
	}
	nStatus = this->pObj->CheckStatus();
	if (ERR_CHECK(nStatus))
	{
		this->StopThread(THREAD_STOP_NOMAL);
		if (nStatus == RT_E_THREAD_FREEZE)
		{
			this ->StopThread(THREAD_STOP_NOMAL);
			this ->pOhj ->ClearFlag();
		}
	}
	return nStatus;
}
//------------------------------------------------------------------

#ifndef _Deque 
#define _Deque 
#include <vector>
using namespace std;
template <class T> 
class Deque : public std::vector<T> 
{
private:
public:
	Deque(void);
	Deque(const int _nSize, const int _nIncrement);
	virtual -Deque(void);
	virtual int Push(const T &_oValue);
	virtual int Pop(T i_pValue);
	virtual int PushFirst(const T &_oValue);
	virtual int PopBack(T St_pValue);
};
template <class T>
Deque<T>::Deque(
	void 
): std::vector<T>::vector()
{
	return;
}
template <class T> 
Deque<T>::Deque(
	const int _nSize 
	, const int _nIncrement 
): std::vector<T>::reserve(_nSize)
{
	return;
}
template <class T> 
Deque<T>::~Deque(
	void 
)
{
	return;
}
template <class T>
int Deque<T>::Push(
	const T  &_oValue 
)
{
	int nStatus;
	nStatus = 0;
	nStatus = std::vector<T>::push_back(_oValue);
	return nStatus;
}
template <class T> 
int Deque<T>::Pop(
	T &pValue 
)
{
	int nStatus;
	nStatus = 0;
	_PValue = std::vector<T>::front();
	std::vector<T>::erase[std::vector<T>::begin()];
	return nStatus;
}
template <class T>
int Deque<T>::PushFirst(
	const T &_oValue 
)
{
	int nStatus;
	nStatus = 0;
	nStatus = std::vector<T>::insert(std::vector<T>::begin(), _oValue);
	return nStatus;
}
template <class T> 
int Deque<T>::PopBack(
	T &_pValue 
)
{
	int nStatus;
	nStatus = 0;
	nStatus = std::vector<T>::pop_back(_pValue);
	return nStatus;
}
#endif 

#ifndef _DataQue 
#define _DataQue 
#include "rt_sts.h" 
#include "Deque.h" 
#include <pthread.h> 
#include <sys/time.h> 
#include <errno.h> 
#define QUE_UNINIT 0 
#define QUE_INITED 1 
#define QUE_DEFAULT_MAX_SIZE 50 
#define QUE_DEFAULT_WAIT_TIME 0 
#define QUE_TIMEVAL_U_N 1000 
template <class T> 
class DataQue 
{
protected:
	Deque<T> oQue;
	pthread_mutex_t mutex;
	pthread_cond_t PushCond;
	pthread_cond_t PopCond;
	int nMaxQue;
	int nTimeout;
	int nInitStatus;
	virtual int Lock(void){
		return(( pthread_mutex_lock(&this->mutex) == 0)? 
			RT_S_SUCCESS : RT_E_LOCK);
	} 
	
	virtual int Unlock(void){ 
		return(( pthread_mutex_unlock(&this ->mutex) == 0)?
			RT_S_SUCCESS : RT_E_UNLOCK);
	}
	virtual int Wait(pthread_cond_t *pCond);
	virtual int TimedWait(pthread_cond_t *pCond);
public:
	DataQue(int _nMaxQue = QUE_DEFAULT_MAX_SIZE,
		int _nMaxTimeout = QUE_DEFAULT_WAIT_TIME);
	DataQue(const DataQue<T> & _o0bj);
	virtual ~DataQue(void);
	virtual int Init(void);
	virtual int Push(T _oData);
	virtual int PushFirst(T _oData);
	virtual int Pop(T & _pData);
	virtual int Size(unsigned int & _nSize)
	virtual int Empty(void);
	virtual int Clear(void);
	virtual DataQue<T> & operator = ( DataQue<T> &_oObj);
};
template <class T>
DataQue<T>::DataQue(
	int _nMaxQue,
	int _nMaxTimeout 
): oQue(_nMaxQue, 1)
{
	this->nTimeout = 0;
	this->nInitStatus = QUE_UNINIT;
	this->nMaxQue = _nMaxQue;
	if (_nMaxTimeout > 0)
	{
		nTimeout = _nMaxTimeout;
	}
}

template<class T> DataQue<T>::DataQue(
	const DataQue<T> & _o0bj 
){ 
	this->nTimeout = 0;
	this->nInitStatus = QUE_UNINIT;
	this->oQue = _oObj.oQue;
	this->nMaxQue = _oObj.nMaxQue;
	this->nTimeout = _oObj.nTimeout;
	pthread_mutex_init(&( this ->mutex), NULL);
	pthread_cond_init(&( this ->PushCond), NULL);
	pthread_cond_init(&( this ->PopCond), NULL);
	this->nInitStatus = QUE_INITED;
	
}

template <class T>
DataQue<T>::~DataQue(
	void 
){ 
	int nStatus;
	nStatus = 0;
	nStatus = pthread_mutex_destroy(&(this->mutex));
	nStatus = pthread_cond_destroy(&(this->PushCond));
	nStatus = pthread_cond_destroy(&(this->PopCond));
}

template <class T> 
int DataQue<T>::Init(
	void 
){
	int nStatus;
	nStatus = 0;
	nStatus = pthread_mutex_init(&( this->mutex), NULL);
	if (nStatus != 0)
	{
		return RT_E_INITIALIZE;
	}
	nStatus = pthread_cond_init(&( this->PushCond), NULL);
	if (nStatus != 0)
	{
		return RT_E_INITIALIZE;
	}
	nStatus = pthread_cond_init(&( this->PopCond), NULL);
	if (nStatus != 0)
	{
		return RT_E_INITIALIZE;
	}
	nStatus = this->oQue.Clear();
	ERR_RETURN(nStatus);
	this->nInitStatus = QUE_INITED;
	return RT_S_SUCCESS;
}
template <class T> 
int DataQue<T>::Push(
	T _oData 
){ 
	int nStatus;
	int nQueSize;
	nStatus = 0;
	nQueSize = 0;
	if (this->nInitStatus != QUE_INITED)
	{
		return RT_E_INITIALIZE;
	}
	nStatus = this->Lock();
	ERR_RETURN(nStatus);
	while (( nQueSize = this->oQue.GetElementSize())>= this->nMaxQue)
	{
		if (this->nTimeout == 0)
		{
			nStatus = this->Wait(&this->PopCond);
		}
		else if (this->nTimeout > 0)
		{ 
			nStatus = this->TimedWait(&this->PopCond);
			
		} 
		if (nStatus != RT_S_SUCCESS)
		{
			this->Unlock();
			return nStatus;
		}
	}
	nStatus = this->oQue.PushFirst(_oData);
	if (ERR_CHECK(nStatus))
	{
		this->Unlock();
		return nStatus;
	}
	nStatus = this->Unlock();
	ERR_RETURN(nStatus);
	nStatus = pthread_cond_broadcast(&( this->PushCond));
	if (nStatus != 0)
	{
		return RT_E_INVAL;
	}
	return RT_S_SUCCESS;
}
template <class I> 
int DataQue<T>::Pop(
	T & _pData 
)
{
	int nStatus;
	int nQueSize;
	nStatus = 0;
	nQueSize = 0;
	if (this->nInitStatus != QUE_INITED)
	{
		return RT_E_INITIALIZE;
	}
	nStatus = this->Lock();
	ERR_RETURN(nStatus);
	while (( nQueSize = this->oQue.GetElementSize())<= 0)
	{
		if (this->nTimeout == 0)
		{
			nStatus = this->Wait(&this->PushCond);
		}
		else if (this->nTimeout > 0)
		{
			nStatus = this->TimedWait(&this->PushCond);
		}
		if (nStatus != RT_S_SUCCESS)
		{
			this->Unlock();
			return nStatus;
		}
	}
	nStatus = this->oQue.PopBack(_pData);
	if (ERR_CHECK(nStatus))
	{
		this->Unlock();
		return nStatus;
	} 
	nStatus = this->Unlock();
	ERR_RETURN(nStatus);
	nStatus = pthread_cond_broadcast(&(this->PopCond));
	if (nStatus != 0)
	{
		return RT_E_INVAL;
	}
	return RT_S_SUCCESS;
}
template <class T> 
int DataQue<T>::Size(
	unsigned int & _nSize 
){
	int nStatus;
	int nElementSize;
	nStatus = 0;
	nElementSize = 0;
	_nSize = 0;
	if (this->nInitStatus != QUE_INITED)
	{
		return RT_E_INITIALIZE;
	}
	nStatus = this->Lock();
	ERR_RETURN(nStatus);
	nElementSize = this->oQue.GetElementSize();
	if (nElementSize > 0)
	{
		_nSize = nElementSize;
	}
	nStatus = this->Unlock();
	ERR_RETURN(nStatus);
	return RT_S_SUCCESS;
} 
template <class T> int DataQue<T>::Empty(
	void 
){ 
	int nStatus;
	int nSize;
	nStatus = 0;
	nSize = 0;
	if (this->nInitStatus != QUE_INITED)
	{
		return RT_E_INITIALIZE;
	} 
	nStatus = this->Lock();
	ERR_RETURN(nStatus);
	nSize = this->oQue.GetElementSize();
	nStatus = this->Unlock();
	ERR_RETURN(nStatus);
	if (nSize <= 0)
	{
		return RT_E_INVAL;
	} 
	return RT_S_SUCCESS;
}
template <class T> int DataQue<T>::Clear(
	void 
){ 
	int nStatus;
	nStatus = 0;
	if (this->nlnitStatus != QUE_INITED)
	{ 
		return RT_E_INITIALIZE;
	}
	nStatus = this->Lock();
	ERR_RETURN(nStatus);
	nStatus = this->oQue.Clear();
	if (ERR_CHECK(nStatus))
	{
		nStatus = this->Unlock();
		return nStatus;
	}
	nStatus = this->Unlock();
	ERR_RETURN(nStatus);
	return RT_S_SUCCESS;
}
template<class T> 
DataQue<T> & DataQue<T>::operator = (
	DataQue<T> & _oObj 
)
{ 
	if (this->nInitStatus == QUE_INITED)
	{
		this ->oQue = _oObj.oQue;
		this ->nMaxQue = _oObj.nMaxQue;
		this ->nTimeout = _oObj.nTimeout;
	}
	return *this;
}
template <class T> 
int DataQue<T>::TimedWait(
	pthread_cond_t *pCond 
){
	int nStatus;
	struct timeval oTv;
	struct timezone oTz;
	struct timespec oTimeout;
	nStatus = 0;
	memset(&oTv, Ox00, sizeof(oTv));
	memset(&oTz, 0x00, sizeof(oTz));
	memset(&oTimeout, Ox00, sizeof(oTimeout));
	nStatus = -1;
	while (nStatus != 0)
	{
		gettimeofday(&oTv &oTz);
		oTimeout.tv_sec = oTv.tv_sec this->nTimeout;
		oTimeout. tv_nsec = oTv. tv_usec * QUE_TIMEVAL_U_N;
		nStatus = pthread_cond_timedwait(
			pCond,
			kthis->mutex,
			&oTimeout
		);
		switch(nStatus)
		{
			case 0:
				break;
			case ETIMEDOUT:
				return RT_W_TIMEOUT;
			case EINTR:
				continue;
			case EFAULT:
			case EINVAL:
				return RT_E_INVAL;
			default:
				return RT_E_ERROR;
		}
	}
	return RT_S_SUCCESS;
}
template <class I> 
int DataQue<T>::Wait(
	pthread_cond_t *pCond 
){
	int nStatus;
	nStatus = -1;
	while (nStatus != 0)
	{
		nStatus = pthread_cond_wait(
			pCond,
			&this->mutex 
		);
		switch(nStatus)
		{
			case 0:
				break;
			case EINTR:
				continue;
			case EFAULT:
			case EINVAL:
				return RT_E_INVAL;
			default:
				return RT_E_ERROR;
		}
	} 
	return RT_S_SUCCESS;
} 
#endif 


#ifndef _GTHREAD_MANAGER_ 
#define _GTHREAD_MANAGER_ 
#include "GThreadGroup.h" 
#include "GThread.h"
class GThreadManager 
: public GThreadGroup
{	
public:
	static GThreadManager* Getinstance();
	GThreadGroup* CreateGroup(const char *_sKey);
	static void Deletelnstance();
private:
	static GThreadManager *pManager;
	static const char *sGroupName;
	GThreadManager(const char* _sKey): GThreadGroup(_sKey){}
	virtual ~GThreadManager0 
};
#endif 
#ifndef _GTHREADGRODP_ 
#define _GTHREADGROUP_ 
#include "GThreadBase h" 
#include "Runnable.h" 
#include "GThread.h" 
#include "String.h" 
#include "Mutex.h" 
#include "rt_sts.h" 
#include "Map.h" 
class GThreadGroup 
: public GThreadBase
{
public:
	virtual int AddThread(
		const char *_sKey 
		, Runnable *_pObj 
		, int _nSetPriority = THREAD_PR1ORITY_DEF 
		, int _nSetPolicy = SCHED_OTHER 
		, int _nSetScope = THREAD_SCOPE_SYSTEM 
	);
	virtual int AddGroup(GThreadGroup *_pObject);
	virtual int StartThread(int _nlnterval)
	{
		return this ->ExecAllObject(EXEC_START_THREAD, _nlnterval);
	}
	virtual int StopThread(int _nMode)
	{
		return this->ExecAllObject(EXEC_STOP_THREAD, _nMode);
	}
	virtual int ActivCount(int &_nCount)
	{
		return this -, ExecAllObject(EXEC_ACTIV_COUNT, _nCount);
	}
	virtual int ThreadCount(int &_nCount)
	{
		return this-, ExecAllObject(EXEC_THREAD_COUNT _nCount);
	}
	virtual int CheckThread()
	{
		int nDummy = 0;
		return this->ExecAllObject(EXEC_CHECK_THREAD, nDummy);
	}
	virtual int GetMaxPriority(int &_nPriority)
	{
		return this-, ExecAllObject(EXEC_MAX_PRIORITY, _nPriority);
	}
	virtual int Join()
	{
		int nDummy = 0;
		return this->ExecAllObject(EXEC_THREAD_JOIN, nDummy);
	}
protected:
	static const int EXEC_START_THREAD = 0;
	static const int EXEC_STOP_THREAD = 1;
	static const int EXEC_ACT1V_COUNT = 2;
	static const int EXEC_THREAD_COUNT = 3;
	static const int EXEC_CHECK_THREAD = 4;
	static const int EXEC_MAX_PRIORITY = 5;
	static const int EXEC_THREAD_JOIN = 6;
	Map< String, GThreadBase*> oThreadMap;
	Mutex ollutex;
	const String sGroupName;
	friend class GThreadManager;
	
	GThreadGroup(const char *_sGroupName);
	virtual ~GThreadGroup();
	virtual int ExecAllObject(int _nExec, int &_nArg);
	virtual int DeleteObject(const char *_sKey);
	virtual int DeleteAllObject();
};
#endif 

#include "GThreadGroup.h" 
#include "rt_log_macro.h" 
#include <new> 
static const char *sProcn[] = {
	"Start thread" 
	, "Stop thread" 
	, "Check activ count" 
	, "Check thread count" 
	, "Check thread status" 
	, "Get max priority "
	, "Thread join"
};

GThreadGroup::GThreadGroup(
	const char *_sGroupName 
): sGroupName(_sGroupName){}

GThreadGroup::~GThreadGroup(
	void 
){
	this->DeleteAllObject();
}
int GThreadGroup::AddThread(
	const char *_sKey 
	, Runnable *_pObject
	, int _nSetPriority 
	, int _nSetPolicy 
	, int _nSetScope
)
{
	int nStatus;
	GThreadBase *pThread;
	String sKey;
	static const char *sMsg = "AddThreadYtKey[ %s ]YtGroup[ %s ]";
	nStatus = 0;
	pThread = NULL;
	NULL_RETURN(_sKey);
	NULL_RETURN(_pObject);
	pThread = new(std::nothrow)GThread(
		_pObject 
		, _nSetPriority 
		, _nSetPolicY
		, _nSetScope 
	);
	ALLOC_RETURN(pThread);
	sKey = _sKey;
	nStatus = this ->oMutex.Lock();
	ERR_RETURN(nStatus);
	nStatus = this ->oThreadMap.Put(sKey, pThread);
	if (ERR_CHECK(nStatus))
	{
		this->ollutex.Unlock();
		return nStatus;
	}
	nStatus = this->ollutex.Unlock();
	ERR_RETURN(nStatus);
	return RT_S_SUCCESS;
}
int GThreadGroup::AddGroup(
	GThreadGroup *_pObject
)
{
	int nStatus;
	const char *sMsg = "AddGroupYtKey[ %s ]YtGroup[ %s ]";
	nStatus = 0;
	NULL_RETURN(_pObject);
	nStatus = this->oMutex.Lock();
	ERR_RETURN(nStatus);
	nStatus = this->oThreadMap.Put(_pObject->sGroupName, _pObject);
	if (ERR_CHECK(nStatus))
	{
		this->oMutex.Unlock();
		return nStatus;
	}
	nStatus = this ->oMutez.Unlock();
	ERR_RETURN(nStatus);
	return RT_S_SUCCESS;
}
int GThreadGroup::DeleteObject(
	const char *_sKey 
)
{
	int nStatus;
	int nObjTYPe;
	GThreadBase *pObject;
	String sKey;
	const char *sMsg = "DeleteThreadVtKey[ %s ]YtGroup[ Ks ]";
	nStatus = 0;
	nObjType = 0;
	pObject = NULL;
	NULL_RETURN(_sKey);
	sKey = _sKey;
	nStatus = this->oMutez.Lock();
	ERR_RETURN(nStatus);
	nStatus = this->oThreadMap.Remove(sKey, pObject);
	if (ERR_CHECK(nStatus))
	{
		this->oMutex. Unlock();
		return nStatus;
	}
	if (pObject == NULL)
	{
		this->oMutex.Unlock();
		return RT_F_NULL_POINTER;
	}		 
	nStatus = this ->oMutex.Unlock();
	ERR_RETURN(nStatus);
	delete pObject;
	pObject = NULL;
	return RT_S_SUCCESS;
}
int GThreadGroup, DeleteAllObject(
	void 
)
{
	int nSize;
	int i;
	int nStatus;
	String sKey;
	GThreadlase *pObject;
	static const char esMsg = "DeleteObjectVtKey[ %s ]itGroup[ Ks ]";
	nSize = 0;
	i = 0;
	nStatus = 0;
	pObject = NULL;
	nStatus = this->oMutex.Lock();
	ERR_RETURN(nStatus);
	nSize = this- oThreadMap.GetElementSize();
	for (i = 0 i < nSize; i++)
	{
		nStatus = this->oThreadMap.GetTolndez(i, sKey, pObject);
		if (ERR_CHECK(nStatus))
		{
			this->oMutex.Unlock();
			return nStatus;
		}
		if (pObject = NULL)
		{
			this->oMutez.Unlock();
			return RT_F_NULL_POINTER;
		}
		delete pObject;
		pObject = NULL;
	} 
	this ->oThreadMap.Clear();
	nStatus = this ->oMutex.Unlock();
	ERR_RETURN(nStatus);
	return RT_S_SUCCESS: 
} 
int GThreadGroup::EzecAllObject(
	int _nEzec
	, int &_nArg 
)
{
	
	int nSize;
	int i;
	int nStatus;
	String sKey;
	GThreadBase *pObject;
	static const char *sMsg =
	"%s VtKey[ %s ]VtGroup[ %s ]";
	static const char *sErrMsg =
	"%s VtKey[ %s ]VtGroup[ %s ]";
	static const char *sinval =
	"Invalid Method Can't Processing [ %d ]";
	nSize = 0;
	i = 0;
	nStatus = 0;
	pObject = NULL;
	nStatus = this->ohlutex.Lock();
	ERR_RETURN(nStatus);
	
	nSize = this->oThreadMap.GetElementSize();
	for (i = 0; i < nSize; i++)
	{
		nStatus = this ->oThreadMap.GetTolndex(i, sKey, pObject);
		if (ERR_CHECK(nStatus))
		{
			this->oMutex.Unlock();
			return nStatus;
		}
		if (pObject = NULL)
		{
			this ->oMutex.Unlock();
			return RT_F_NULL_POINTER;
		}
		switch(_nExec)
		{ 
			case EXEC_START_THREAD:
				nStatus = pObject->StartThread(_nArg);
				break;
			case EXEC_STOP_THREAD:
				nStatus = pObject->StopThread(_nArg);
				break;
			case EXEC_ACTIV_COUNT:
				nStatus pObject->ActivCount(_nArg);
				break;
			case EXEC_THREAD_COUNT:
				nStatus = pObject->ThreadCount(_nArg);
				break;
			case EXEC_CHECK_THREAD:
				nStatus = pObject- CheckThread();
				break;
			case EXEC_MAX_PRIORITY:
				nStatus = pObject->GetMaxPriority(_nArg);
				break;
			case EXEC_THREAD_JOIN:
				nStatus = pObject->Join();
				break;
			default:
				this -, oMutex.Unlock();
				RT_LOG_FORMAT_START(RT_E_INVAL)
				, slnval 
				, _nExec
				RT_LOG_END;
				return RT_E_INVAL;
				break;
		}
		if (ERR_CHECK(nStatus))
		{
			RT_LOG_FORMAT_START(nStatus)
			, sErrMsg 
			, sProc[_nExec] 
			, sKey.C_Str()
			, this->sGroupName.C_Str()
			RT_LOG_END;
			this ->oMutex.Unlock();
			return nStatus;
		}
	}
	nStatus = this ->oMutex.Unlock();
	ERR_RETURN(nStatus);
	return RT_S_SUCCESS;
}
