📄 unixthreads.cpp
字号:
} else { //There was no message to get retVal=HXR_FAIL; } m_pCondLock->Unlock(); } return retVal;}HX_RESULT HXUnixThread::DispatchMessage(HXThreadMessage* pMsg){ HX_ASSERT( "HXUnixThread::DispatchMessage is not implemented yet." == NULL ); return HXR_FAIL;}//=======================================================================//// HXUnixMutex// ------------------////=======================================================================HXUnixMutex::HXUnixMutex(){} HXUnixMutex::~HXUnixMutex(){}HX_RESULT HXUnixMutex::MakeMutex( HXMutex*& pMutex ){#if defined( _LINUX ) || defined(_HPUX) || defined(_MAC_UNIX) pMutex = new HXPthreadMutex();#elif defined( _SOLARIS ) pMutex = new HXSolarisMutex();#else HX_ASSERT( "No unix mutex for this platform" == NULL );#endif if(pMutex == NULL) { HX_ASSERT( 0 ); return HXR_OUTOFMEMORY; } return HXR_OK;}HX_RESULT HXUnixMutex::Lock(){ return _Lock();} HX_RESULT HXUnixMutex::Unlock(){ return _Unlock();} HX_RESULT HXUnixMutex::Trylock(){ return _TryLock();}//=======================================================================//// HXUnixSemaphore// ------------------////=======================================================================HXUnixSemaphore::HXUnixSemaphore(UINT32 unInitialCount) : m_unInitialCount(unInitialCount){}HXUnixSemaphore::~HXUnixSemaphore(){}HX_RESULT HXUnixSemaphore::MakeSemaphore(HXUnixSemaphore*& pSem){#if defined( _LINUX ) || defined(_HPUX) pSem = new HXPthreadSemaphore();#elif defined(_MAC_UNIX) pSem = new HXPthreadMacSemaphore();#elif defined( _SOLARIS ) pSem = new HXSolarisSemaphore();#else HX_ASSERT( "No unix semaphore for this platform" == NULL );#endif if(pSem == NULL) { HX_ASSERT(0); return HXR_OUTOFMEMORY; } return HXR_OK;} HX_RESULT HXUnixSemaphore::Post(){ return _Post();}HX_RESULT HXUnixSemaphore::Wait(){ return _Wait();}HX_RESULT HXUnixSemaphore::TryWait(){ return _TryWait();}HX_RESULT HXUnixSemaphore::GetValue( int* pnCount){ return _GetValue( pnCount );}//=======================================================================//// HXUnixEvent// ------------------////======================================================================= HXUnixEvent::HXUnixEvent(const char* pEventName, BOOL bManualReset) : m_bIsManualReset( bManualReset ), m_bEventIsSet(FALSE), m_pCondLock(NULL), m_pCond(NULL){ // // NOTE: Because of the way the windows Cond vars work we have: // // bManualReset==1 Once we signal once, all other signal/wait // calls are noops. All threads awake. // bManualReset==0 Once signaled we retain until someone Waits. // Once someone waits, only one thread wakes up // and the signal is reset. // //Create the condition with its associated mutex. //Do NOT delete the mutex that the cond makes for us.... HXUnixCondition::MakeCondition(m_pCond, m_pCondLock ); HX_ASSERT( m_pCondLock && m_pCond);}HXUnixEvent::~HXUnixEvent(){ //Do NOT delete the mutex that the cond makes for us.... HX_DELETE( m_pCond ); m_pCondLock = NULL;}HX_RESULT HXUnixEvent::SignalEvent(){ //Lock it all down. m_pCondLock->Lock(); //Whether or not this is manual reset, set the state. m_bEventIsSet = TRUE; //Signal the event depending on what type it is. if( m_bIsManualReset ) { //Manual reset, wake up all threads. All waits become noops //until the event is reset. m_pCond->Broadcast(); } else { m_pCond->Signal(); } //Unlock it and go. m_pCondLock->Unlock(); return HXR_OK;}HX_RESULT HXUnixEvent::Wait( UINT32 uTimeoutPeriod ){ HX_RESULT res = HXR_OK; m_pCondLock->Lock(); //Check to see if this event has already been signaled. if( m_bEventIsSet ) { //If we are not manual reset and we are signaled. reset the //signaled flag before returning. if( !m_bIsManualReset ) { m_bEventIsSet = FALSE; } m_pCondLock->Unlock(); return HXR_OK; } //We are not manual reset. if(uTimeoutPeriod!=ALLFS) { //XXXgfw We can be woken up by signals before the event is //actually signaled or the time has elapsed. Not sure what to //do in that case yet. Since most implementations try to //minimize these wakups I will just ignore it for now since we //are just using condtionals to mimic Window's events. res = m_pCond->TimedWait(uTimeoutPeriod); } else { m_pCond->Wait(); } //Now, if we just woke up and the event had been signaled, We need //reset the event. if( !m_bIsManualReset && m_bEventIsSet ) { m_bEventIsSet = FALSE; } //Now that we have waited m_pCondLock->Unlock(); return res;}HX_RESULT HXUnixEvent::ResetEvent(){ m_pCondLock->Lock(); m_bEventIsSet = FALSE; m_pCondLock->Unlock(); return HXR_OK;}void* HXUnixEvent::GetEventHandle(){ //XXXgfw This doesn't look like it is used right now. Assuming we //just want it to be a unique handle to this event, we can use the //this pointer to the cond class we made. return (void*)m_pCond;}//=======================================================================//// HXUnixCondition// ---------------------////=======================================================================HXUnixCondition::HXUnixCondition(){};HXUnixCondition::~HXUnixCondition(){};HX_RESULT HXUnixCondition::MakeCondition( HXUnixCondition*& pCond, HXUnixMutex*& pMutex ){ HX_ASSERT( pMutex==NULL); #if defined( _LINUX ) && defined(_UNIX_THREADS_SUPPORTED) || defined(_MAC_UNIX) pCond = (HXUnixCondition*) new HXPthreadCondition(pMutex);#elif defined(_SOLARIS) pCond = (HXUnixCondition*) new HXSolarisCondition(pMutex);#else HX_ASSERT( "No unix condtional for this platform" == NULL );#endif if(pCond == NULL ) { HX_ASSERT(0); return HXR_OUTOFMEMORY; } HX_ASSERT( pMutex ); return HXR_OK;}HX_RESULT HXUnixCondition::Wait(){ HX_RESULT ret; ret = _Wait(); return ret;}HX_RESULT HXUnixCondition::TimedWait( UINT32 uTimeoutPeriod ){ return _TimedWait(uTimeoutPeriod);}HX_RESULT HXUnixCondition::Broadcast(){ return _Broadcast();}HX_RESULT HXUnixCondition::Signal(){ return _Signal();}//=======================================================================//// HXUnixAsyncTimer// -----------------------////======================================================================= //Static data initializersHXMutex* HXUnixAsyncTimer::m_pmtxMapLock = NULL;CHXMapLongToObj HXUnixAsyncTimer::m_mapTimers;//Timeouts are in miliseconds.HXUnixAsyncTimer::HXUnixAsyncTimer( ULONG32 ulTimeOut, HXThread* pReceivingThread ) : m_ulTimeOut( ulTimeOut ), m_pReceivingThread( pReceivingThread ), m_pMessagePump( NULL ), m_pMsg(NULL), m_pfExecFunc(NULL){ //Make the message to pump. m_pMsg = new HXThreadMessage( HXMSG_ASYNC_TIMER, (void*)m_ulTimeOut, NULL, NULL ); //Start the thread. We have to do this weird casting because //the HXThread::MakeThread takes HXThread*&.... HXThread* pTmp = NULL; HXUnixThread::MakeThread(pTmp); HX_ASSERT( pTmp ); m_pMessagePump = (HXUnixThread*)pTmp; m_pMessagePump->CreateThread( _ActualMessagePump, (void*)this );}HXUnixAsyncTimer::HXUnixAsyncTimer( ULONG32 ulTimeOut, TIMERPROC pfExecFunc ) : m_ulTimeOut( ulTimeOut ), m_pReceivingThread(NULL), m_pMessagePump(NULL), m_pMsg(NULL), m_pfExecFunc( pfExecFunc ){ //we need non-null pfExecFunc HX_ASSERT( m_pfExecFunc != NULL ); //Start the thread. HXThread* pTmp = NULL; HXUnixThread::MakeThread(pTmp); HX_ASSERT( pTmp ); m_pMessagePump = (HXUnixThread*)pTmp; m_pMessagePump->CreateThread( _ActualMessagePump, (void*)this );}HXUnixAsyncTimer::~HXUnixAsyncTimer() { //Tell the message pump to quit. HXThreadMessage msgQuit(HXMSG_QUIT, NULL, NULL); m_pMessagePump->PostMessage( &msgQuit ); //Wait for it to stop. m_pMessagePump->JoinThread(); HX_DELETE( m_pMessagePump );}ULONG32 HXUnixAsyncTimer::GetID(){ ULONG32 ulTmp=0; m_pMessagePump->GetThreadId(ulTmp); return ulTmp;}//XXXgfw just to keep the below more readable.#define PARG ((HXUnixAsyncTimer*)pArg)void* HXUnixAsyncTimer::_ActualMessagePump(void* pArg){ while(1) { if( HXR_OK == PARG->m_pMessagePump->PeekMessage(&PARG->m_msgTmp)) { //Got a message. If it is HXMSG_QUIT get our of here. if( PARG->m_msgTmp.m_ulMessage == HXMSG_QUIT ) { break; } } microsleep( PARG->m_ulTimeOut*1000 ); if( PARG->m_pMsg != NULL ) PARG->m_pReceivingThread->PostMessage( PARG->m_pMsg); else PARG->m_pfExecFunc( 0, 0, PARG->GetID(), GetTickCount() ); } return NULL;}#undef PARGUINT32 HXUnixAsyncTimer::SetTimer(ULONG32 ulTimeOut, HXThread* pReceivingThread ){ if( m_pmtxMapLock == NULL ) { HXMutex::MakeMutex( m_pmtxMapLock ); HX_ASSERT( m_pmtxMapLock ); } //lock it. m_pmtxMapLock->Lock(); ULONG32 ulTimerID = 0; HX_ASSERT( ulTimeOut != 0 ); HX_ASSERT( pReceivingThread != NULL ); HXUnixAsyncTimer* pTimer = new HXUnixAsyncTimer(ulTimeOut, pReceivingThread ); HX_ASSERT( pTimer != NULL ); if( pTimer != NULL ) { //Add new timer to map. ulTimerID = pTimer->GetID(); m_mapTimers.SetAt( ulTimerID, (void*)pTimer ); } //unlock the map. m_pmtxMapLock->Unlock(); return ulTimerID;}UINT32 HXUnixAsyncTimer::SetTimer(ULONG32 ulTimeOut, TIMERPROC pfExecFunc ){ if( m_pmtxMapLock == NULL ) { HXMutex::MakeMutex( m_pmtxMapLock ); HX_ASSERT( m_pmtxMapLock ); } //lock it. m_pmtxMapLock->Lock(); ULONG32 ulTimerID = 0; HX_ASSERT( ulTimeOut != 0 ); HX_ASSERT( pfExecFunc != NULL ); HXUnixAsyncTimer* pTimer = new HXUnixAsyncTimer(ulTimeOut, pfExecFunc ); HX_ASSERT( pTimer != NULL ); if( pTimer != NULL ) { //Add new timer to map. ulTimerID = pTimer->GetID(); m_mapTimers.SetAt( ulTimerID, (void*)pTimer ); } //unlock the map. m_pmtxMapLock->Unlock(); return ulTimerID;}BOOL HXUnixAsyncTimer::KillTimer(UINT32 ulTimerID ){ //lock it. m_pmtxMapLock->Lock(); BOOL bRetVal = FALSE; void* pTimer = NULL; HX_ASSERT( ulTimerID != 0 ); if( m_mapTimers.Lookup( ulTimerID, pTimer ) ) { //Found it. bRetVal = TRUE; HXUnixAsyncTimer* pTmp = (HXUnixAsyncTimer*)pTimer; HX_DELETE(pTmp); m_mapTimers.RemoveKey( ulTimerID ); } //unlock the map. m_pmtxMapLock->Unlock(); return bRetVal;}#endif //_UNIX_THREADS_SUPPORTED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -