Esempio n. 1
0
// this thread is signaled when the system wakes from a suspend state
DWORD WINAPI
ResumeThreadProc(LPVOID lpvParam)
{
    DWORD dwStatus;
    HANDLE hevReady = (HANDLE) lpvParam;
    HANDLE hEvents[2];
    BOOL fDone = FALSE;
    INT iPriority;
    SETFNAME(_T("ResumeThreadProc"));

    PMLOGMSG(ZONE_INIT, (_T("+%s: thread 0x%08x\r\n"), pszFname, GetCurrentThreadId()));

    // set the thread priority
    if(!GetPMThreadPriority(_T("ResumePriority256"), &iPriority)) {
        iPriority = DEF_RESUME_THREAD_PRIORITY;
    }
    CeSetThreadPriority(GetCurrentThread(), iPriority);

    // we're up and running
    SetEvent(hevReady);

    // wait for new devices to arrive
    hEvents[0] = ghevResume;
    hEvents[1] = ghevPmShutdown;
    while(!fDone) {
        dwStatus = WaitForMultipleObjects(dim(hEvents), hEvents, FALSE, INFINITE);
        switch(dwStatus) {
        case (WAIT_OBJECT_0 + 0):
            PMLOGMSG(ZONE_RESUME, (_T("%s: resume event signaled\r\n"), pszFname));
            PlatformResumeSystem();
            break;
        case (WAIT_OBJECT_0 + 1):
            PMLOGMSG(ZONE_WARN, (_T("%s: shutdown event set\r\n"), pszFname));
            fDone = TRUE;
            break;
        default:
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
                                 pszFname, dwStatus, GetLastError()));
            fDone = TRUE;
            break;
        }
    }

    PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
    return 0;
}
Esempio n. 2
0
// 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;

#ifndef SHIP_BUILD
    SETFNAME(_T("ActivityTimersThreadProc"));
#endif

    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;
}
Esempio n. 3
0
DWORD WINAPI 
PnpThreadProc(LPVOID lpvParam)
{
    DWORD dwStatus;
    HANDLE hnGeneric = NULL;
    HANDLE hevReady = (HANDLE) lpvParam;
    HANDLE hEvents[MAXIMUM_WAIT_OBJECTS];
    DWORD dwNumEvents = 0;
    BOOL fDone = FALSE;
    BOOL fOk;
    INT iPriority;
    PDEVICE_LIST pdl;
    SETFNAME(_T("PnpThreadProc"));

    PMLOGMSG(ZONE_INIT, (_T("+%s: thread 0x%08x\r\n"), pszFname, GetCurrentThreadId()));

    // set the thread priority
    if(!GetPMThreadPriority(_T("PnPPriority256"), &iPriority)) {
        iPriority = DEF_PNP_THREAD_PRIORITY;
    }
    CeSetThreadPriority(GetCurrentThread(), iPriority);

    // first list entry is the exit event
    hEvents[dwNumEvents++] = ghevPmShutdown;

    // set up device notifications
    for(pdl = gpDeviceLists; pdl != NULL && dwNumEvents < dim(hEvents); pdl = pdl->pNext) {
        hEvents[dwNumEvents++] = pdl->hMsgQ;
        pdl->hnClass = RequestDeviceNotifications(pdl->pGuid, pdl->hMsgQ, TRUE);
        if(pdl->hnClass == NULL) {
            PMLOGMSG(ZONE_WARN, (_T("%s: RequestDeviceNotifications() failed %d\r\n"),
                pszFname, GetLastError()));
        }
    }
    DEBUGCHK(dwNumEvents > 1);
    // we're up and running
    SetEvent(hevReady);
    
    // Wait for Initalization complete.
    HANDLE hInit[2] = {ghevPowerManagerReady, ghevPmShutdown};
    fDone = (WaitForMultipleObjects(_countof(hInit), hInit, FALSE, INFINITE)!= WAIT_OBJECT_0);

    // wait for new devices to arrive
    while(!fDone) {
        dwStatus = WaitForMultipleObjects(dwNumEvents, hEvents, FALSE, INFINITE);
        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 && dwStatus <= (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) { 
            dwStatus -= WAIT_OBJECT_0;
            fOk = ProcessPnPMsgQueue(hEvents[dwStatus]);
            if(!fOk) {
                PMLOGMSG(ZONE_WARN, (_T("%s: ProcessPnPMsgQueue(0x%08x) failed\r\n"), pszFname,
                    hEvents[dwStatus]));
            }
        } else {
            PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"),
                pszFname, dwStatus, GetLastError())); 
            fDone = TRUE;
            break;
        }
    }

    // release resources
    for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) {
        if(pdl->hnClass != NULL) StopDeviceNotifications(pdl->hnClass);
    }

    // all done
    PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname));
    return 0;
}
Esempio n. 4
0
EXTERN_C VOID WINAPI
PlatformManageSystemPower (HANDLE hevReady)
{
	BOOL fDone = FALSE;
	HANDLE hqNotify = NULL;
	HMODULE hmCoreDll = NULL;

	SETFNAME (_T ("PlatformManageSystemPower"));

	PMLOGMSG (ZONE_INIT || ZONE_PLATFORM, (_T ("+%s\r\n"), pszFname));

	// Initialize globals:
	ghevReloadActivityTimeouts = NULL;
	ghevRestartTimers = NULL;

	// Determine thread priority settings while we're suspending (in case
	// of priority inversion):

	if (!GetPMThreadPriority (_T ("PreSuspendPriority256"), &giPreSuspendPriority))
	{
		giPreSuspendPriority = DEF_PRESUSPEND_THREAD_PRIORITY;
	}
	if (!GetPMThreadPriority (_T ("SuspendPriority256"), &giSuspendPriority))
	{
		giSuspendPriority = DEF_SUSPEND_THREAD_PRIORITY;
	}

	// Get pointers to GWES's suspend/routine APIs.  These require GWES, so the OEM may
	// not have them on this platform.  Also get battery level APIs, which require a
	// battery driver and may not be present.

	hmCoreDll = (HMODULE) LoadLibrary (_T ("coredll.dll"));
	gfGwesReady = FALSE;
	PmInitPowerStatus (hmCoreDll);
	if (hmCoreDll != NULL)
	{
		gpfnGwesPowerDown = (PFN_GwesPowerDown) GetProcAddress (hmCoreDll, _T ("GwesPowerDown"));
		gpfnGwesPowerUp = (PFN_GwesPowerUp) GetProcAddress (hmCoreDll, _T ("GwesPowerUp"));

		// Do we have both GWES suspend/resume APIs?
		if (gpfnGwesPowerDown == NULL || gpfnGwesPowerUp == NULL)
		{
			// No, ignore GWES.
			gpfnGwesPowerDown = NULL;
			gpfnGwesPowerUp = NULL;
		}
	}

	// Create events:
	ghevReloadActivityTimeouts =
		CreateEvent (NULL, FALSE, FALSE, _T ("PowerManager/ReloadActivityTimeouts"));
	ghevRestartTimers = CreateEvent (NULL, FALSE, FALSE, NULL);
	if (ghevReloadActivityTimeouts == NULL || ghevRestartTimers == NULL)
	{
		PMLOGMSG (ZONE_WARN, (_T ("%s: CreateEvent() failed for system event\r\n"), pszFname));
		goto done;
	}

	// Create our notification queue:
	hqNotify = PmPolicyCreateNotificationQueue ();
	if (hqNotify == NULL)
	{
		PMLOGMSG (ZONE_WARN, (_T ("%s: PmPolicyCreateNotificationQueue() failed\r\n"), pszFname));
		goto done;
	}

	if (!fDone)
	{
        // Instantiate the PowerStateManager object and call its Init method:

		PowerStateManager *pPowerStateManager = new PowerStateManager ();

		if (pPowerStateManager && pPowerStateManager->Init ())
		{
			g_pPowerStateManager = pPowerStateManager;

			// We're up and running:
			SetEvent (hevReady);
			g_pPowerStateManager->ThreadRun ();
		}
		else
		{
            // Power Manager initialization failed:
			ASSERT (FALSE);
			if (pPowerStateManager)
				delete pPowerStateManager;

			PMLOGMSG (ZONE_INIT || ZONE_ERROR,
					  (_T ("%s: PowerStateManager Intialization Failed!!!\r\n"), pszFname));
		}
		if (g_pPowerStateManager)
		{
			delete g_pPowerStateManager;
			g_pPowerStateManager = NULL;
		}
	}

  done:
	// Clean up before exiting:
	if (ghevReloadActivityTimeouts == NULL)
	{
		CloseHandle (ghevReloadActivityTimeouts);
		ghevReloadActivityTimeouts = NULL;
	}
	if (ghevRestartTimers != NULL)
	{
		CloseHandle (ghevRestartTimers);
		ghevRestartTimers = NULL;
	}
	if (hqNotify != NULL)
	{
		PmPolicyCloseNotificationQueue (hqNotify);
		hqNotify = NULL;
	}

	if (hmCoreDll != NULL)
		FreeLibrary (hmCoreDll);

	PMLOGMSG (ZONE_PLATFORM, (_T ("-%s: exiting\r\n"), pszFname));
}