⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unixthreads.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }
    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 initializers
HXMutex*       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 PARG

UINT32 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 + -