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

📄 wcetimer.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//

#include "dhcpv6p.h"
#include "wcetim.h"


////////////////////////////////////////////////////////////////////////////////
//	CE_ScheduleWorkItem()
//
//	Routine Description:
//
//		This function uses cxport to schedule work item..
//
//	Arguments:
//		
//		None.
//
//	Return Value:
//
//		TRUE if successful, FALSE otherwise..
//
//	Note:
//
//		The called function ** MUST ** clear the CTE_EVENT_DATA struct 
//		allocated here..
//	

BOOL
CE_ScheduleWorkItem(
    CTEEventRtn pFunction,
    PVOID       pvArg)
{

    PCTE_EVENT_DATA     pCteEventData;

    pCteEventData = MemCAlloc(sizeof(CTE_EVENT_DATA));

    if (pCteEventData)
    {
        CTEInitEvent(
            &(pCteEventData->hCTEEvent), 
            pFunction);

        if (!CTEScheduleEvent(
                &(pCteEventData->hCTEEvent), 
                pvArg))
        {
            ASSERT(0);
        }

        return TRUE;
    }
    else
    {
        DEBUGMSG (ZONE_ERROR,
        (TEXT("ZCF:: Alloc() failed in CE_ScheduleWorkItem().\r\n")));

        return FALSE;
    }

}	//	CE_ScheduleWorkItem()



//////////////////////////////////////////////////////////////////////////////
//  CE emulation of TimerQueue 
///////////////////////////////////////////////////////////////////////////////


LIST_ENTRY          g_TimerQueueList;
CRITICAL_SECTION    g_csTimerQueueList;
HANDLE		        g_hDefaultTimerQueue = NULL;

#ifdef DEBUG
DWORD               g_dwTotalTQ     = 0x00;
DWORD               g_dwTotalTQT    = 0x00;
#endif


///////////////////////////////////////////////////////////////////////////////
//	PerformCallback()
//
//	Routine Description:
//
//	    CTE calls this, and we call the actual function.
//
//	Arguments:
//		
//		pCteTimer   ::  * Not used *.
//      pvData      ::  Should point to PTIMER_QUEUE_TIMER.
//
//	Return Value:
//
//		None.
//

void
PerformCallback(CTETimer *pCteTimer, PVOID pvData)
{
    PTIMER_QUEUE_TIMER  pTimerQueueTimer = (PTIMER_QUEUE_TIMER) pvData;    
    
    //
    //  The actual callback..
    //

    ASSERT(pTimerQueueTimer->dwSig == CE_TIMERTIMER_SIG);

    EnterCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);


    DEBUGMSG (ZONE_TIMER,
        (TEXT("ZCF:: PerformCallback() TQT[0x%x]..\r\n"),
        pTimerQueueTimer));

    //
    //  bTimerRunning == FALSE indicates we need to quit now..
    //

    if (pTimerQueueTimer->bTimerRunning == FALSE)
    {
        DEBUGMSG (ZONE_TIMER,
            (TEXT("ZCF:: PerformCallback() TQT[0x%x] forced terminated..\r\n"),
            pTimerQueueTimer));

        CTESignal(&pTimerQueueTimer->TimerBlockStruc, ERROR_SUCCESS);
        LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
        TQT_DELREF(pTimerQueueTimer);   //  Taken in CE_CreateTimerQueueTimer() for completion.
        return;
    }

    //
    //  Arriving here means this is timer expiration..
    //  Mark it that we are going into callback function.
    //  The reason is because call back function may call ChangeTimer() in which
    //  we should just update the TimerQueueTimer structure and restart the timer
    //  in this function (i.e instead of in the ChangeTimer() function).
    //

    pTimerQueueTimer->bTimerInCallBack = TRUE;
    LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);

    pTimerQueueTimer->Callback(pTimerQueueTimer->Parameter, TRUE);

    EnterCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
    pTimerQueueTimer->bTimerInCallBack = FALSE;
    if (pTimerQueueTimer->bTimerRunning == FALSE)
    {
        DEBUGMSG (ZONE_TIMER,
            (TEXT("ZCF:: PerformCallback() TQT[0x%x] forced terminated..\r\n"),
            pTimerQueueTimer));

        CTESignal(&pTimerQueueTimer->TimerBlockStruc, ERROR_SUCCESS);
        LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
        TQT_DELREF(pTimerQueueTimer);   //  Taken in CE_CreateTimerQueueTimer() for completion.
        return;
    }

    if (pTimerQueueTimer->DueTime)
    {
        //
        //  The call back may call changetimer to restart with another due time, honor it.
        //
        
        CTEStartTimer(
            &(pTimerQueueTimer->hTimer),
            pTimerQueueTimer->DueTime,
            (CTEEventRtn)PerformCallback,
            pTimerQueueTimer);        
        
        LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
    }
    else
    if (pTimerQueueTimer->Period)
    {   
        //
        //  Restart the timer..
        //

        DEBUGMSG (ZONE_TIMER,
            (TEXT("ZCF:: PerformCallback() TQT[0x%x] Restarted for period [%d].\r\n"),
            pTimerQueueTimer,
            pTimerQueueTimer->Period));
        
        
        CTEStartTimer(
            &(pTimerQueueTimer->hTimer),
            pTimerQueueTimer->Period,
            (CTEEventRtn)PerformCallback,
            pTimerQueueTimer);

        LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
    }
    else
    {
        //
        //  One shot timer.. 
        //

        DEBUGMSG (ZONE_TIMER,
            (TEXT("ZCF:: PerformCallback() TQT[0x%x] 1 time timer terminated.\r\n"),
            pTimerQueueTimer));
        
        pTimerQueueTimer->bTimerRunning = FALSE;
        LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
        TQT_DELREF(pTimerQueueTimer);   //  Taken in CE_CreateTimerQueueTimer() for completion.
    }
}   //  PerformCallback()


///////////////////////////////////////////////////////////////////////////////
//	WCE_Initialize()
//
//	Routine Description:
//
//		Called during initialization..
//
//	Return Value:
//
//		TRUE if successful, FALSE otherwise..
//

BOOL
WCE_Initialize()
{
#if 0
    BOOL    bStatus = FALSE;    
    
    do
    {
        //
        //  Async IO support.
        //
        
        g_AsyncWorkerWakeUpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

        if (g_AsyncWorkerWakeUpEvent == NULL)
            break;
            
        InitializeCriticalSection (&g_csAsyncWorkItem);

        InitializeListHead(&g_pAsyncWorkItemQueue);
        g_dwTotalPendingAsyncWorkItem   = 0x00;
        
        InitializeListHead(&g_pFreeAsyncWorkItem);
        g_dwTotalFreeAsyncWorkItem      = 0x00;
        
        InitializeListHead(&g_pHandleMappingList);        
        InitializeCriticalSection(&g_csHandleMappingList);

        InitializeCriticalSection (&g_csThreads);
        g_dwTotalAsyncWorkerThread      = 0x00;
        g_dwTotalFreeAsyncWorkerThread  = 0x00;
        g_bGlobalAsyncThreadQuit        = FALSE;


        //
        //  RegisterWaitForSingleObject() support.
        //

        InitializeCriticalSection(&g_csWaitForSingleObjectThread);
        InitializeListHead(&g_WaitObjectList);

        g_ReenumEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

        if (g_ReenumEvent == NULL)
            break;
        
#endif
        //
        //  TimerQueue support.
        //

        InitializeListHead(&g_TimerQueueList);
        InitializeCriticalSection(&g_csTimerQueueList);
        return TRUE;

#if 0
#ifdef  TEST_CE_SPECIFIC_CODE
{
        extern void            
        CETestThread(PVOID Param1);
        
        HANDLE  hThread;
        DWORD   dwThreadId;
        
        hThread = CreateThread(
                            NULL, 
                            0, 
                            (LPTHREAD_START_ROUTINE) CETestThread,
                            NULL,
                            0,
                            &dwThreadId);

        if (hThread != NULL)
            CloseHandle(hThread);
}
#endif
        
        bStatus = TRUE;    
    }
    while (FALSE);

    if (!bStatus)
    {

        DEBUGMSG (ZONE_ERR,
            (TEXT("IPv6Hlp:: ** Failed ** WCE_Initialize.\r\n")));
            
        if (g_AsyncWorkerWakeUpEvent)
            CloseHandle(g_AsyncWorkerWakeUpEvent);

        if (g_ReenumEvent)
            CloseHandle(g_ReenumEvent);
        
    }
    return bStatus;
#endif

}



///////////////////////////////////////////////////////////////////////////////
//	CE_CreateTimerQueue()
//
//	Routine Description:
//
//		This function prepares the structures for subsequent calls to
//      CE_CreateTimerQueueTimer.
//
//	Arguments:
//		
//		None.
//
//	Return Value:
//
//		NULL if fail.
//

HANDLE
CE_CreateTimerQueue(void)
{
    PTIMER_QUEUE    pTimerQueue;

    pTimerQueue = (PTIMER_QUEUE) MALLOC(sizeof(TIMER_QUEUE));   
    
    if (pTimerQueue == NULL)
        return (HANDLE)INVALID_HANDLE_VALUE;

    memset(pTimerQueue, 0x00, sizeof(TIMER_QUEUE));

#ifdef DEBUG
	pTimerQueue->dwSig = CE_TIMER_SIG;
#endif

    InitializeCriticalSection(&pTimerQueue->csTimerQueue);

    InitializeListHead(&pTimerQueue->TimerQueueTimerList);

    //
    //  Derefed in CE_DeleteTimerQueueTimer()
    //

    TQ_ADDREF(pTimerQueue);

    //
    //  Queue this to global timer queue..
    //

    EnterCriticalSection(&g_csTimerQueueList);

    InsertHeadList(&g_TimerQueueList, (PLIST_ENTRY)pTimerQueue);

    LeaveCriticalSection(&g_csTimerQueueList);

    DEBUGMSG(
        ZONE_TIMER,
        (TEXT("ZCF:: CreateTimerQueue() returning handle [0x%x], TotalTQ[%d]\r\n"),
        pTimerQueue,
        InterlockedIncrement(&g_dwTotalTQ)));

    return (HANDLE)pTimerQueue;

}   //  CE_CreateTimerQueue()



///////////////////////////////////////////////////////////////////////////////
//	CE_DeleteTimerQueue()
//
//	Routine Description:
//
//		This function tries to FREE the TIMER_QUEUE structure if ref reaches
//      zero.   Regardless, it will wipe out the signature so the next
//      CreateTimerQueueTimer() on it will fail.
//      
//
//	Arguments:
//		
//		hTimerQueue :: Should be the handle returned by CE_CreateTimerQueue()
//
//	Return Value:
//
//		TRUE if successful, FALSE otherwise..
//

BOOL
CE_DeleteTimerQueue(HANDLE  hTimerQueue)
{
    PTIMER_QUEUE            pTimerQueue;


    DEBUGMSG (ZONE_TIMER,
        (TEXT("ZCF:: Deleting TimerQueue [0x%x]\r\n"),
        hTimerQueue));

    //
    //  Find it in our list..
    //

    EnterCriticalSection(&g_csTimerQueueList);

    pTimerQueue = (PTIMER_QUEUE)g_TimerQueueList.Flink;

    while (pTimerQueue != NULL)
    {
        if (pTimerQueue == (PTIMER_QUEUE)hTimerQueue)
            break;

        pTimerQueue = (PTIMER_QUEUE)pTimerQueue->ListEntry.Flink;
    }

    if (pTimerQueue == NULL)
    {
        //
        //  This should not happen in our ZCF code.
        //
        
        ASSERT(0);
        LeaveCriticalSection(&g_csTimerQueueList);
        return FALSE;
    }    

    EnterCriticalSection(&pTimerQueue->csTimerQueue);

    ASSERT(pTimerQueue->dwSig == CE_TIMER_SIG);

    //
    //  Cancel and delete all existing TimerQueueTimer
    //

    while (!IsListEmpty(&pTimerQueue->TimerQueueTimerList))
    {
        DEBUGMSG (ZONE_TIMER,
            (TEXT("ZCF:: Force deleting TimerQueueTimer[0x%x].\r\n"),
            pTimerQueue->TimerQueueTimerList.Flink));
            
        DeleteTimerQueueTimer(
            pTimerQueue,
            (PTIMER_QUEUE_TIMER)(pTimerQueue->TimerQueueTimerList.Flink),
            INVALID_HANDLE_VALUE);
    }

    LeaveCriticalSection(&pTimerQueue->csTimerQueue);    


    //
    //  Take it out from the list..
    //

    RemoveEntryList((PLIST_ENTRY)pTimerQueue);

    LeaveCriticalSection(&g_csTimerQueueList);

    TQ_DELREF(pTimerQueue);     //  Taken in CE_CreateTimerQueue()
    
    return TRUE;

}   //  CE_DeleteTimerQueue()



///////////////////////////////////////////////////////////////////////////////
//	FindAndRefTimerQueue()
//
//	Routine Description:
//
//		This function tries to find pTimerQueue in g_TimerQueueList list.
//      
//
//	Return Value:
//
//		NULL if not found, otherwise point to TimerQueue that's refed.
//      Caller needs to unref.
//

PTIMER_QUEUE
FindAndRefTimerQueue(PTIMER_QUEUE  pTargetTimerQueue)
{
    PTIMER_QUEUE            pTimerQueue;

    //
    //  Find it in our list..
    //

    EnterCriticalSection(&g_csTimerQueueList);

    pTimerQueue = (PTIMER_QUEUE)(g_TimerQueueList.Flink);

    while ((PLIST_ENTRY)pTimerQueue != &g_TimerQueueList)
    {
        if (pTimerQueue == pTargetTimerQueue)
            break;

        pTimerQueue = (PTIMER_QUEUE)(pTimerQueue->ListEntry.Flink);
    }

    if ((PLIST_ENTRY)pTimerQueue == &g_TimerQueueList)
    {
        LeaveCriticalSection(&g_csTimerQueueList);
        return NULL;
    }

    //
    //  Take the REF, caller needs to deref.
    //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -