📄 wcetimer.c
字号:
//
// 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 + -