📄 pmtimer.cpp
字号:
// update the timeout value
if(dwTimeout == INFINITE || dwTimeLeft < dwTimeout) {
dwTimeout = dwTimeLeft;
}
// update the timer
pat->dwTimeLeft = dwTimeLeft;
}
}
PMUNLOCK();
return dwTimeout;
}
// this thread handles activity timer events
DWORD WINAPI
ActivityTimersThreadProc(LPVOID lpvParam)
{
DWORD dwStatus, dwNumEvents, dwWaitInterval;
HANDLE hevReady = (HANDLE) lpvParam;
HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
BOOL fDone = FALSE;
HANDLE hevDummy = NULL;
INT iPriority;
const DWORD cdwTimerBaseIndex = 2;
SETFNAME(_T("ActivityTimersThreadProc"));
PMLOGMSG(ZONE_INIT, (_T("+%s: thread 0x%08x\r\n"), pszFname, GetCurrentThreadId()));
// set the thread priority
if(!GetPMThreadPriority(_T("TimerPriority256"), &iPriority)) {
iPriority = DEF_ACTIVITY_TIMER_THREAD_PRIORITY;
}
CeSetThreadPriority(GetCurrentThread(), iPriority);
// initialize the list of activity timers
if(ActivityTimerInitList() != ERROR_SUCCESS) {
PMLOGMSG(ZONE_WARN, (_T("%s: ActivityTimerInitList() failed\r\n"), pszFname));
goto done;
}
// create a dummy event that's never signaled
hevDummy = CreateEvent(NULL, FALSE, FALSE, NULL);
if(hevDummy == NULL) {
PMLOGMSG(ZONE_WARN, (_T("%s: Couldn't create dummy event\r\n"), pszFname));
goto done;
}
// set up the list of events
dwNumEvents = 0;
hEvents[dwNumEvents++] = ghevPmShutdown;
hEvents[dwNumEvents++] = ghevTimerResume;
PMLOCK();
if(gppActivityTimers[0] == NULL) {
// no activity timers defined
PmFree(gppActivityTimers);
gppActivityTimers = NULL;
} else {
// copy activity timer events into the event list
while(dwNumEvents < dim(hEvents) && gppActivityTimers[dwNumEvents - cdwTimerBaseIndex] != NULL) {
hEvents[dwNumEvents] = gppActivityTimers[dwNumEvents - cdwTimerBaseIndex]->hevReset;
dwNumEvents++;
}
}
PMUNLOCK();
// we're up and running
SetEvent(hevReady);
// are there actually any timers to wait on?
if(dwNumEvents <= cdwTimerBaseIndex) {
// no timers defined, so we don't need this thread to wait on them.
PMLOGMSG(ZONE_INIT || ZONE_WARN, (_T("%s: no activity timers defined, exiting\r\n"), pszFname));
Sleep(1000); // don't want PM initialization to fail when we exit
goto done;
}
// wait for these events to get signaled
PMLOGMSG(ZONE_TIMERS, (_T("%s: entering wait loop, %d timers total\r\n"),
pszFname, dwNumEvents - cdwTimerBaseIndex));
dwWaitInterval = 0;
while(!fDone) {
DWORD dwTimeout = GetNextInactivityTimeout(dwWaitInterval);
DWORD dwWaitStart = GetTickCount();
PMLOGMSG(ZONE_TIMERS,
(_T("%s: waiting %u (0x%08x) ms for next event, wait interval was %d\r\n"), pszFname,
dwTimeout, dwTimeout, dwWaitInterval));
dwStatus = WaitForMultipleObjects(dwNumEvents, hEvents, FALSE, dwTimeout);
dwWaitInterval = GetTickCount() - dwWaitStart;
// figure out what caused the wakeup
if(dwStatus == (WAIT_OBJECT_0 + 0)) {
PMLOGMSG(ZONE_WARN, (_T("%s: shutdown event set\r\n"), pszFname));
fDone = TRUE;
} else if(dwStatus == (WAIT_OBJECT_0 + 1)) {
DWORD dwIndex;
PACTIVITY_TIMER pat;
// we've resumed, so re-enable all activity timers that can be reset
PMLOGMSG(ZONE_TIMERS, (_T("%s: resume event set\r\n"), pszFname));
PMLOCK();
for(dwIndex = 0; (pat = gppActivityTimers[dwIndex]) != NULL; dwIndex++) {
DWORD dwEventIndex = dwIndex + cdwTimerBaseIndex;
if(hEvents[dwEventIndex] == hevDummy) {
hEvents[dwEventIndex] = pat->hevReset;
}
pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
}
PMUNLOCK();
} else if(dwStatus == WAIT_TIMEOUT) {
DWORD dwIndex;
PACTIVITY_TIMER pat;
// figure out which event(s) timed out
PMLOCK();
for(dwIndex = 0; (pat = gppActivityTimers[dwIndex]) != NULL; dwIndex++) {
if(pat->dwTimeLeft <= dwWaitInterval && pat->dwTimeLeft != INFINITE) {
// has the timer really expired?
if(WaitForSingleObject(pat->hevReset, 0) == WAIT_OBJECT_0) {
// The timer was reset while we weren't looking at it, so we'll look
// at it again later. Calculate the new timeout, compensating for the update
// that will occur in GetNextInactivityTimeout().
PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' reset after timeout\r\n"), pszFname,
pat->pszName));
pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
pat->dwResetCount++;
} else {
// the timer has really expired, update events appropriately
PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' has expired\r\n"), pszFname,
pat->pszName));
ResetEvent(pat->hevActive);
SetEvent(pat->hevInactive);
// start looking at the reset event for this timer again
hEvents[dwIndex + cdwTimerBaseIndex] = pat->hevReset;
// update counts
pat->dwTimeLeft = INFINITE;
pat->dwExpiredCount++;
}
}
}
PMUNLOCK();
} else if(dwStatus > (WAIT_OBJECT_0 + 0) && dwStatus < (WAIT_OBJECT_0 + dwNumEvents)) {
PACTIVITY_TIMER pat;
DWORD dwEventIndex = dwStatus - WAIT_OBJECT_0;
PMLOCK();
// get a pointer to the timer
pat = gppActivityTimers[dwEventIndex - cdwTimerBaseIndex];
// handle its events
DEBUGCHK(pat != NULL);
if(pat->dwTimeout == 0) {
// we're not using the event, so ignore it
pat->dwTimeLeft = INFINITE;
} else {
PMLOGMSG(ZONE_TIMERS, (_T("%s: timer '%s' reset\r\n"), pszFname, pat->pszName));
// set events appropriately
ResetEvent(pat->hevInactive);
SetEvent(pat->hevActive);
// don't look at this event again until it's about ready to time out
hEvents[dwEventIndex] = hevDummy;
// update time left on the timer, compensating for the update
// that will occur in GetNextInactivityTimeout().
pat->dwTimeLeft = pat->dwTimeout + dwWaitInterval;
}
pat->dwResetCount++;
PMUNLOCK();
} else {
PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
pszFname, dwStatus, GetLastError()));
fDone = TRUE;
}
}
done:
// release resources
if(hevDummy != NULL) CloseHandle(hevDummy);
PMLOCK();
if(gppActivityTimers != NULL) {
DWORD dwIndex = 0;
while(gppActivityTimers[dwIndex] != NULL) {
ActivityTimerDestroy(gppActivityTimers[dwIndex]);
dwIndex++;
}
PmFree(gppActivityTimers);
gppActivityTimers = NULL;
}
PMUNLOCK();
PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -