Initial commit
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#else //!WIN32
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <semaphore.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "typedef.h"
|
||||
#include "debug.h"
|
||||
#include "thread.h"
|
||||
|
||||
|
||||
CSema::CSema(const char *sName, unsigned int nInit, bool bCreate)
|
||||
{
|
||||
m_bCreate = bCreate;
|
||||
if (!m_bCreate)
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
m_hSema = CreateSemaphore(NULL,nInit,0xffff,NULL);
|
||||
if (!m_hSema){
|
||||
#else
|
||||
semCount = nInit;
|
||||
if( pthread_mutex_init(&mutex, NULL) || pthread_cond_init(&condition, NULL) ){
|
||||
#endif
|
||||
DebugPrint("Create semaphore error, errno=%d\n", errno );
|
||||
}
|
||||
}
|
||||
|
||||
CSema::~CSema()
|
||||
{
|
||||
if (!m_bCreate)
|
||||
return;
|
||||
int rc = 0;
|
||||
#ifdef _WIN32
|
||||
if( !(rc=CloseHandle(m_hSema)) ){
|
||||
#else
|
||||
rc = pthread_mutex_destroy(&mutex);
|
||||
if( rc ){
|
||||
DebugPrint( "destroy mutex ret %d\n", rc );
|
||||
}
|
||||
rc = pthread_cond_destroy(&condition);
|
||||
if( rc ){
|
||||
#endif
|
||||
DebugPrint("delete semaphore error %d\n", rc );
|
||||
}
|
||||
}
|
||||
|
||||
int CSema::ActP(DWORD dwTimeout)
|
||||
{
|
||||
if (!m_bCreate)
|
||||
return -1;
|
||||
|
||||
int ret;
|
||||
#ifdef _WIN32
|
||||
ret = WaitForSingleObject(m_hSema, dwTimeout);
|
||||
if( ret==WAIT_TIMEOUT ){
|
||||
#else
|
||||
if( dwTimeout==INFINITE ){
|
||||
if( (ret=pthread_mutex_lock(&mutex))==0 ){
|
||||
while( semCount<=0 ){
|
||||
if( (ret=pthread_cond_wait(&condition, &mutex)) ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !ret )
|
||||
semCount--;
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
else{
|
||||
DebugPrint( "lock mutex error %d.\n", ret );
|
||||
}
|
||||
}
|
||||
else{
|
||||
if( (ret = pthread_mutex_lock(&mutex))==0 ){
|
||||
timeval tv;
|
||||
// struct timezone tz;
|
||||
timespec tm;
|
||||
gettimeofday (&tv , /*&tz*/NULL);
|
||||
|
||||
tm.tv_sec = tv.tv_sec + dwTimeout/1000 + ( tv.tv_usec + (dwTimeout%1000)*1000 ) / 1000000;
|
||||
tm.tv_nsec = 1000 * ( ( tv.tv_usec + (dwTimeout%1000)*1000 ) % 1000000 );
|
||||
|
||||
while( semCount<=0 ){
|
||||
if( (ret=pthread_cond_timedwait( &condition, &mutex, &tm )) ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !ret )
|
||||
semCount--;
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
}
|
||||
else{
|
||||
DebugPrint( "Lock mutext error %d.\n", ret );
|
||||
}
|
||||
}
|
||||
|
||||
if( ret==ETIMEDOUT ){
|
||||
#endif
|
||||
// DebugPrint("WaitforSingleObject timeout!\n");
|
||||
return 1;
|
||||
}
|
||||
else if( ret!=0 ){
|
||||
DebugPrint( "sema wait error. errno=%d\n", errno );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CSema::ActV()
|
||||
{
|
||||
if (!m_bCreate)
|
||||
return;
|
||||
#ifdef _WIN32
|
||||
if (!ReleaseSemaphore(m_hSema,1,NULL)){
|
||||
#else
|
||||
int rc;
|
||||
if( (rc = pthread_mutex_lock(&mutex)) ){
|
||||
DebugPrint("mutex lock error.errno=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
if( semCount<=0 )
|
||||
semCount ++;
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
rc = pthread_cond_signal(&condition);
|
||||
|
||||
if( rc ){
|
||||
#endif
|
||||
DebugPrint("sema post error.errno=%d\n", errno);
|
||||
}
|
||||
}
|
||||
|
||||
CMutexLock::CMutexLock(bool bCreate)
|
||||
{
|
||||
m_psmMut = new CSema( NULL, 1, bCreate );
|
||||
|
||||
m_psmMut->ActP();
|
||||
}
|
||||
|
||||
CMutexLock::CMutexLock(CSema * pSema, DWORD dwTimeOut)
|
||||
{
|
||||
m_psmMut = pSema;
|
||||
|
||||
m_psmMut->ActP(dwTimeOut);
|
||||
}
|
||||
|
||||
CMutexLock::~CMutexLock()
|
||||
{
|
||||
if( m_psmMut!=NULL )
|
||||
m_psmMut->ActV();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CThread::CThread(unsigned int stackSize, EPriority priorityLevel)
|
||||
#ifndef _WIN32
|
||||
: m_smSuspend( NULL, 0 ), m_smSleep( NULL, 0 )
|
||||
#endif
|
||||
{
|
||||
if(stackSize<=0){
|
||||
DebugPrint("CThread 输入参数不正确\n");
|
||||
}
|
||||
|
||||
m_bSuspend = true;
|
||||
m_bExit = false;
|
||||
m_nStackSize = stackSize;
|
||||
|
||||
// DebugPrint("create CThread with stacksize of %d\n", stackSize);
|
||||
#ifdef _WIN32
|
||||
m_hThreadHandle = (HANDLE)_beginthreadex(NULL, stackSize, MainFunction,
|
||||
this, CREATE_SUSPENDED, &m_nThreadId);
|
||||
// m_bSuspend = true;
|
||||
#else
|
||||
pthread_attr_init(&m_tAttr);
|
||||
pthread_attr_setstacksize( &m_tAttr, stackSize );
|
||||
//pthread_attr_setschedpolicy( &m_tAttr, SCHED_RR ); //SCHED_RR 或者 SCHED_FIFO,程序必须要在超级用户下运行,否则失败
|
||||
m_hThreadHandle = 0;
|
||||
// SetPriority(e_LowestPriority);
|
||||
// DebugPrint( "Set thread attributes.\n" );
|
||||
//pthread_create( &m_hThreadHandle, &m_tAttr, MainFunction, this );
|
||||
// DebugPrint("CThread constructure finished.\n" );
|
||||
#endif
|
||||
|
||||
SetPriority(priorityLevel);
|
||||
}
|
||||
|
||||
CThread::~CThread()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if( m_hThreadHandle != NULL ){
|
||||
DWORD dwExitCode = 0;
|
||||
if( GetExitCodeThread(m_hThreadHandle, &dwExitCode)==0){
|
||||
DebugPrint("PThread::~PThread,GetExitCode failed errorcode=%d\n", GetLastError());
|
||||
}
|
||||
else if( dwExitCode==STILL_ACTIVE ){
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject(m_hThreadHandle,100)){
|
||||
TerminateThread(m_hThreadHandle, 2);
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(m_hThreadHandle);
|
||||
}
|
||||
#else
|
||||
pthread_join( m_hThreadHandle, NULL );
|
||||
pthread_attr_destroy( &m_tAttr );
|
||||
#endif
|
||||
}
|
||||
|
||||
void CThread::ExitThread()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_endthreadex(0);
|
||||
#else
|
||||
pthread_exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
unsigned int __stdcall CThread::MainFunction(void *threadPtr)
|
||||
#else
|
||||
void* CThread::MainFunction(void *threadPtr)
|
||||
#endif
|
||||
{
|
||||
if(threadPtr==NULL){
|
||||
DebugPrint("CThread::MainFunction threadPtr is NULL!\n");
|
||||
}
|
||||
else{
|
||||
CThread *thread = (CThread *)threadPtr;
|
||||
// DebugPrint("Get CThread object 0x%X\n", (long)thread );
|
||||
thread->Main();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
return 0;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CThread::Suspend()
|
||||
{
|
||||
if (m_bSuspend) return;
|
||||
|
||||
// DebugPrint( "Suspend in.\n" );
|
||||
m_bSuspend = true;
|
||||
#ifdef _WIN32
|
||||
SuspendThread(m_hThreadHandle);
|
||||
#else
|
||||
m_smSuspend.ActP();
|
||||
#endif
|
||||
|
||||
// DebugPrint( "Suspend out.\n" );
|
||||
}
|
||||
|
||||
void CThread::Terminate()
|
||||
{
|
||||
if (m_bExit) return;
|
||||
|
||||
m_bExit = true;
|
||||
}
|
||||
|
||||
void CThread::Resume()
|
||||
{
|
||||
if (!m_bSuspend) return;
|
||||
|
||||
m_bSuspend = false;
|
||||
|
||||
// DebugPrint( "Resume call.\n" );
|
||||
|
||||
#ifdef _WIN32
|
||||
ResumeThread(m_hThreadHandle);
|
||||
#else
|
||||
if( !m_hThreadHandle ){
|
||||
int err = pthread_create( &m_hThreadHandle, &m_tAttr, MainFunction, this );
|
||||
if(err!=0)
|
||||
DebugPrint( "create pthread return %d\n", err );
|
||||
}
|
||||
else{
|
||||
m_smSuspend.ActV();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void CThread::SetPriority(EPriority priorityLevel)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int nPrior;
|
||||
|
||||
switch (priorityLevel){
|
||||
case e_LowestPriority:
|
||||
nPrior = THREAD_PRIORITY_LOWEST;
|
||||
break;
|
||||
case e_LowPriority:
|
||||
nPrior = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
break;
|
||||
case e_NormalPriority:
|
||||
nPrior = THREAD_PRIORITY_NORMAL;
|
||||
break;
|
||||
case e_HighPriority:
|
||||
nPrior = THREAD_PRIORITY_ABOVE_NORMAL;
|
||||
break;
|
||||
case e_HighestPriority:
|
||||
nPrior = THREAD_PRIORITY_TIME_CRITICAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!SetThreadPriority(m_hThreadHandle,nPrior)) {
|
||||
#else
|
||||
int policy;
|
||||
pthread_attr_getschedpolicy( &m_tAttr, &policy );
|
||||
int max = sched_get_priority_max( policy );
|
||||
int min = sched_get_priority_min( policy );
|
||||
|
||||
sched_param sp;
|
||||
pthread_attr_getschedparam( &m_tAttr, &sp );
|
||||
sp.sched_priority = priorityLevel * (max-min) / (e_NumPriorities-1) + 1;
|
||||
|
||||
if( -1==pthread_attr_setschedparam(&m_tAttr, &sp) ){
|
||||
#endif
|
||||
DebugPrint("set priority failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CThread::Sleep(DWORD dwMilliseconds)
|
||||
{
|
||||
// DebugPrint( "Sleep %dms\n", dwMilliseconds );
|
||||
#ifdef _WIN32
|
||||
::Sleep(dwMilliseconds);
|
||||
#else
|
||||
m_smSleep.ActP( dwMilliseconds );
|
||||
#endif
|
||||
// DebugPrint( "Sleep %dms over\n", dwMilliseconds );
|
||||
}
|
||||
Reference in New Issue
Block a user