BOOL CMclMailbox::GetAlertable( void *lpMsg, CMclEvent *pInterrupt, DWORD dwTimeout) { BOOL bStatus = FALSE; DWORD dwStatus = pInterrupt->WaitForTwo( *m_cPendingCountSemaphoreAPtr, FALSE, dwTimeout); if (CMclWaitSucceeded( dwStatus, 2) && (CMclWaitSucceededIndex(dwStatus) == 1)) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize); IncrementHead(); m_cGuardMutexAPtr->Release(); bStatus = TRUE; // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cFreeCountSemaphoreAPtr->Release(1); } } return bStatus; }
DWORD CMclMailbox::GetAlertable( void *lpMsg, const CMclWaitableCollection & rCollection, DWORD dwTimeout) { CMclWaitableCollection cCollection; cCollection.AddObject(*m_cPendingCountSemaphoreAPtr); cCollection.AddCollection(rCollection); int nObjects = cCollection.GetCount(); DWORD dwStatus = cCollection.Wait( FALSE, dwTimeout); if (CMclWaitSucceeded( dwStatus, nObjects) && (CMclWaitSucceededIndex(dwStatus) == 0)) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize); IncrementHead(); m_cGuardMutexAPtr->Release(); dwStatus = WAIT_OBJECT_0; // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cFreeCountSemaphoreAPtr->Release(1); } } return dwStatus; }
BOOL CMclMailbox::Get( void *lpMsg, DWORD dwTimeout) { DWORD dwStatus = m_cPendingCountSemaphoreAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1)) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize); IncrementHead(); m_cGuardMutexAPtr->Release(); // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cFreeCountSemaphoreAPtr->Release(1); } } return (CMclWaitSucceeded(dwStatus, 1)); }
VOID FxWakeInterruptMachine::ProcessEventInner( __inout FxPostProcessInfo* Info ) { KIRQL irql; FxWakeInterruptEvents event; const FxWakeInterruptStateTable* entry; FxWakeInterruptStates newState; // // Process as many events as we can // for ( ; ; ) { // // Acquire state machine *queue* lock // Lock(&irql); if (IsEmpty()) { // // The queue is empty. // GetFinishedState(Info); Unlock(irql); return; } // // Get the event from the queue // event = m_Queue[GetHead()]; IncrementHead(); // // Drop the state machine *queue* lock // Unlock(irql); // // Get the state table entry for the current state // // NOTE: Prefast complains about buffer overflow if (m_CurrentState == // WakeInterruptMax), but that should never happen because WakeInterruptMax is not a real // state. We just use it to represent the maximum value in the enum that // defines the states. // __analysis_assume(m_CurrentState < WakeInterruptMax); entry = &m_StateTable[m_CurrentState - WakeInterruptFailed]; // // Based on the event received, figure out the next state // newState = WakeInterruptMax; for (ULONG i = 0; i < entry->TargetStatesCount; i++) { if (entry->TargetStates[i].WakeInterruptEvent == event) { DO_EVENT_TRAP(&entry->TargetStates[i]); newState = entry->TargetStates[i].WakeInterruptState; break; } } if (newState == WakeInterruptMax) { // // Unexpected event for this state // DoTraceLevelMessage( m_PkgPnp->GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP, "WDFDEVICE 0x%p !devobj 0x%p wake interrupt state " "%!FxWakeInterruptStates! dropping event " "%!FxWakeInterruptEvents!", m_PkgPnp->GetDevice()->GetHandle(), m_PkgPnp->GetDevice()->GetDeviceObject(), m_CurrentState, event ); COVERAGE_TRAP(); } while (newState != WakeInterruptMax) { DoTraceLevelMessage( m_PkgPnp->GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNPPOWERSTATES, "WDFDEVICE 0x%p !devobj 0x%p entering wake interrupt " "state %!FxWakeInterruptStates! from " "%!FxWakeInterruptStates!", m_PkgPnp->GetDevice()->GetHandle(), m_PkgPnp->GetDevice()->GetDeviceObject(), newState, m_CurrentState ); // // Update the state history array // m_States.History[IncrementHistoryIndex()] = (UCHAR) newState; // // Move to the new state // m_CurrentState = (BYTE) newState; entry = &m_StateTable[m_CurrentState-WakeInterruptFailed]; // // Invoke the state entry function (if present) for the new state // if (entry->StateFunc != NULL) { newState = entry->StateFunc(this); } else { newState = WakeInterruptMax; } } } return; }