📄 symbianthreads.cpp
字号:
} else { //There was no message to get retVal=HXR_FAIL; } m_pmtxQue->Unlock(); } return retVal;}HX_RESULT HXSymbianThread::DispatchMessage(HXThreadMessage* pMsg){ HX_ASSERT( "HXSymbianThread::DispatchMessage is not implemented yet." == NULL ); return HXR_FAIL;}TInt HXSymbianThread::_ThreadWrapper(TAny* pExecStruct){ TInt nRetVal = KErrNone; st_execStruct* pstExec = (st_execStruct*)pExecStruct; //Install a handle to the global manager for this thread. HXGlobalManInstance::SetInstance(pstExec->pGlobalManager); //Install an active Scheduler for this thread. CActiveScheduler* pSched = new CActiveScheduler(); CActiveScheduler::Install(pSched); //Call the thread. nRetVal = pstExec->pfExecProc(pstExec->pExecArg); CActiveScheduler::Install(0); HX_DELETE(pSched); return nRetVal;}//=======================================================================//// HXSymbianMutex// ------------------////=======================================================================HXSymbianMutex::HXSymbianMutex() : m_pCritSec(NULL), m_bInited(FALSE), m_pCritSecLck(NULL), m_ulOwnerThread(0), m_ulLockCount(0){} HXSymbianMutex::~HXSymbianMutex(){ if( m_pCritSec ) { m_pCritSec->Close(); HX_DELETE(m_pCritSec); } if( m_pCritSecLck ) { m_pCritSecLck->Close(); HX_DELETE(m_pCritSecLck); } m_bInited = FALSE;}HX_RESULT HXSymbianMutex::_Init(){ TInt err1 = KErrNone; TInt err2 = KErrNone; HX_RESULT res = HXR_FAIL; if( !m_bInited) { m_pCritSec = new RCriticalSection; if( m_pCritSec ) { err1 = m_pCritSec->CreateLocal(); } m_pCritSecLck = new RCriticalSection; if( m_pCritSecLck ) { err2 = m_pCritSecLck->CreateLocal(); } } if( m_pCritSec && m_pCritSecLck && KErrNone==err1 && KErrNone==err2 ) { res = HXR_OK; m_bInited = TRUE; } return res;}HX_RESULT HXSymbianMutex::Lock(){ HX_RESULT res = HXR_OK; RThread me; //XXXgfw I wonder if the check every time is too much of a perf //hit. if( !m_bInited ) { res = _Init(); if( FAILED(res) ) return res; } m_pCritSecLck->Wait(); if( m_ulOwnerThread != me.Id() ) { m_pCritSecLck->Signal(); m_pCritSec->Wait(); m_pCritSecLck->Wait(); m_ulOwnerThread = me.Id(); //Make sure the lock count is always zero when we hand off a //mutex to another thread. Otherwise there was too many //unlocks or the like. HX_ASSERT( m_ulLockCount == 0 ); m_ulLockCount = 1; } else { //We alread have it locked. Just increment the lock count m_ulLockCount++; } m_pCritSecLck->Signal(); return res;} HX_RESULT HXSymbianMutex::Unlock(){ HX_RESULT res = HXR_OK; RThread me; //XXXgfw I wonder if the check every time is too much of a perf //hit. if( !m_bInited ) { res = _Init(); if( FAILED(res) ) return res; } m_pCritSecLck->Wait(); HX_ASSERT( m_ulLockCount != 0 && m_ulOwnerThread == me.Id() ); if( m_ulLockCount == 0 || m_ulOwnerThread!=me.Id() ) { m_pCritSecLck->Signal(); return HXR_FAIL; } if( m_ulLockCount == 1 ) { //We are really done with it. Do the real unlock now. m_pCritSec->Signal(); m_ulOwnerThread = 0; m_ulLockCount=0; } else { m_ulLockCount--; } m_pCritSecLck->Signal(); return res;} HX_RESULT HXSymbianMutex::Trylock(){ HX_RESULT res = HXR_OK; RThread me; //XXXgfw I wonder if the check every time is too much of a perf //hit. if( !m_bInited ) { res = _Init(); if( FAILED(res) ) return res; } m_pCritSecLck->Wait(); if( m_pCritSec->IsBlocked() ) { //Someone has it. HX_ASSERT( m_ulOwnerThread != 0 ); HX_ASSERT( m_ulLockCount != 0 ); if( m_ulOwnerThread == me.Id() ) { //It us. m_ulLockCount++; res = HXR_OK; } else { //We would block on it. res = HXR_FAIL; } } else { //No one has it. grab it now. HX_ASSERT( m_ulOwnerThread == 0 ); HX_ASSERT( m_ulLockCount == 0 ); m_pCritSec->Wait(); m_ulLockCount=1; m_ulOwnerThread = me.Id(); res = HXR_OK; } m_pCritSecLck->Signal(); return res;}//=======================================================================//// HXSymbianEvent// ------------------////======================================================================= HXSymbianEvent::HXSymbianEvent(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. // m_pCond = new RSemaphore(); if( m_pCond ) { m_pCond->CreateLocal(0); } HXMutex* pTmp = NULL; HXMutex::MakeMutex(pTmp); m_pCondLock = (HXSymbianMutex*)pTmp; HX_ASSERT( m_pCondLock && m_pCond ); //We ignore the EventName for now...}HXSymbianEvent::~HXSymbianEvent(){ if( m_pCond ) { m_pCond->Close(); HX_DELETE( m_pCond ); } HX_DELETE(m_pCondLock);}HX_RESULT HXSymbianEvent::Wait( UINT32 uTimeoutPeriod ){ HX_RESULT res = HXR_OK; //Symbian does not support timed waits... HX_ASSERT( uTimeoutPeriod==ALLFS); m_pCondLock->Lock(); //Check to see if this event has already been signaled. if( !m_bEventIsSet ) { //We must wait on the event then.... m_pCondLock->Unlock(); m_pCond->Wait(); m_pCondLock->Lock(); } //If we are not manual reset and we are signaled. reset the //signaled flag before returning otherwise leave it signaled for //everyone else that comes in to wait. if( !m_bIsManualReset ) m_bEventIsSet = FALSE; //Now that we have waited m_pCondLock->Unlock(); return res;}HX_RESULT HXSymbianEvent::ResetEvent(){ m_pCondLock->Lock(); m_bEventIsSet = FALSE; m_pCondLock->Unlock(); return HXR_OK;}HX_RESULT HXSymbianEvent::SignalEvent(){ //Lock it all down. m_pCondLock->Lock(); //Whether or not this is manual reset, set the state. m_bEventIsSet = TRUE; //See if anyone is waiting on this event or not... int nCount = m_pCond->Count(); //Signal the event depending on what type it is. if( m_bIsManualReset && nCount<0 ) { //Manual reset, wake up all threads. All waits become noops //until the event is reset. //XXXgfw symbian has no 'broadcast' kind of option. We can //fake it by getting the sem count and calling signal that //much. m_pCond->Signal(Abs(nCount)); } else { m_pCond->Signal(); } //Unlock it and go. m_pCondLock->Unlock(); return HXR_OK;}void* HXSymbianEvent::GetEventHandle(){ return (void*)m_pCond;}//=======================================================================//// HXSymbianAsyncTimer// -----------------------////======================================================================= UINT32 HXSymbianAsyncTimer::SetTimer(ULONG32 ulTimeOut, HXThread* pReceivingThread ){ //lock it. GetMapLock()->Lock(); ULONG32 ulTimerID = 0; HX_ASSERT( ulTimeOut != 0 ); HX_ASSERT( pReceivingThread != NULL ); HXSymbianAsyncTimerImp* pTimer = CreateTimer(); HX_ASSERT( pTimer != NULL ); if( pTimer != NULL ) { pTimer->Init(ulTimeOut, pReceivingThread ); //Add new timer to map. ulTimerID = pTimer->GetID(); GetMapTimers().SetAt( ulTimerID, (void*)pTimer ); } //unlock the map. GetMapLock()->Unlock(); return ulTimerID;}UINT32 HXSymbianAsyncTimer::SetTimer(ULONG32 ulTimeOut, TIMERPROC pfExecFunc ){ //lock it. GetMapLock()->Lock(); ULONG32 ulTimerID = 0; HX_ASSERT( ulTimeOut != 0 ); HX_ASSERT( pfExecFunc != NULL ); HXSymbianAsyncTimerImp* pTimer = CreateTimer(); HX_ASSERT( pTimer != NULL ); if( pTimer != NULL ) { pTimer->Init(ulTimeOut, pfExecFunc ); //Add new timer to map. ulTimerID = pTimer->GetID(); GetMapTimers().SetAt( ulTimerID, (void*)pTimer ); } //unlock the map. GetMapLock()->Unlock(); return ulTimerID;}BOOL HXSymbianAsyncTimer::KillTimer(UINT32 ulTimerID ){ //lock it. GetMapLock()->Lock(); BOOL bRetVal = FALSE; void* pTimer = NULL; HX_ASSERT( ulTimerID != 0 ); if( GetMapTimers().Lookup( ulTimerID, pTimer ) ) { //Found it. HXSymbianAsyncTimerImp* pTmp = (HXSymbianAsyncTimerImp*)pTimer; bRetVal = TRUE; // delete is not used because the timer // may need to delay it's destruction. // The Destroy() call hides this detail pTmp->Destroy(); pTmp = 0; GetMapTimers().RemoveKey( ulTimerID ); } //unlock the map. GetMapLock()->Unlock(); return bRetVal;}HXSymbianAsyncTimerImp* HXSymbianAsyncTimer::CreateTimer(){ HXSymbianAsyncTimerImp* pRet = 0;#if defined USE_SYMBIAN_THREADS_FOR_ASYNCTIMERS pRet = new HXSymbianThreadAsyncTimer;#else pRet = new HXSymbianRTimerAsyncTimer;#endif return pRet;}static void DestroyMapLock(GlobalType pObj){ HXMutex* pMapLock = (HXMutex*)pObj; delete pMapLock;}HXMutex* HXSymbianAsyncTimer::GetMapLock(){ static const HXMutex* const z_pMapLock = NULL; HXGlobalManager* pGM = HXGlobalManager::Instance(); GlobalPtr ptr = pGM->Get(&z_pMapLock); if (!ptr) { HXMutex* pMapLock = 0; HXMutex::MakeMutex(pMapLock); ptr = pGM->Add(&z_pMapLock, pMapLock, &DestroyMapLock); } return (HXMutex*)(*ptr);}CHXMapLongToObj& HXSymbianAsyncTimer::GetMapTimers(){ static const CHXMapLongToObj* const z_pMapTimers = NULL; return HXGlobalMapLongToObj::Get(&z_pMapTimers);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -