{
PKDPC_DATA DpcData;
PLIST_ENTRY ListHead, DpcEntry;
PKDPCDpc;
PKDEFERRED_ROUTINE DeferredRoutine;
PVOIDDeferredContext, SystemArgument1, SystemArgument2;
ULONG_PTR TimerHand;
#ifdef CONFIG_SMPKIRQLOldIrql;
#endif/* Get data and list variables before starting anything else */
DpcData = &Prcb->DpcData[DPC_NORMAL];
ListHead = &DpcData->DpcListHead;
/* Main outer loop */do
{
/* Set us as active */
Prcb->DpcRoutineActive = TRUE;
/* Check if this is a timer expiration request */if (Prcb->TimerRequest)
{
/* It is, get the timer hand and disable timer request */
TimerHand = Prcb->TimerHand;
Prcb->TimerRequest = 0;
/* Expire timers with interrups enabled */_enable();
KiTimerExpiration(NULL, NULL, (PVOID)TimerHand, NULL);
_disable();
}
/* Loop while we have entries in the queue */while (DpcData->DpcQueueDepth != 0)
{
/* Lock the DPC data and get the DPC entry*/KeAcquireSpinLockAtDpcLevel(&DpcData->DpcLock);
DpcEntry = ListHead->Flink;
/* Make sure we have an entry */if (DpcEntry != ListHead)
{
/* Remove the DPC from the list */RemoveEntryList(DpcEntry);
Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
/* Clear its DPC data and save its parameters */
Dpc->DpcData = NULL;
DeferredRoutine = Dpc->DeferredRoutine;
DeferredContext = Dpc->DeferredContext;
SystemArgument1 = Dpc->SystemArgument1;
SystemArgument2 = Dpc->SystemArgument2;
/* Decrease the queue depth */
DpcData->DpcQueueDepth--;
/* Clear DPC Time */
Prcb->DebugDpcTime = 0;
/* Release the lock */KeReleaseSpinLockFromDpcLevel(&DpcData->DpcLock);
/* Re-enable interrupts */_enable();
/* Call the DPC */
DeferredRoutine(Dpc,
DeferredContext,
SystemArgument1,
SystemArgument2);
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
/* Disable interrupts and keep looping */_disable();
}
else
{
/* The queue should be flushed now */ASSERT(DpcData->DpcQueueDepth == 0);
/* Release DPC Lock */KeReleaseSpinLockFromDpcLevel(&DpcData->DpcLock);
}
}
/* Clear DPC Flags */
Prcb->DpcRoutineActive = FALSE;
Prcb->DpcInterruptRequested = FALSE;
#ifdef CONFIG_SMP/* Check if we have deferred threads */if (Prcb->DeferredReadyListHead.Next)
{
/* Re-enable interrupts and raise to synch */_enable();
OldIrql = KeRaiseIrqlToSynchLevel();
/* Process deferred threads */KiProcessDeferredReadyList(Prcb);
/* Lower IRQL back and disable interrupts */KeLowerIrql(OldIrql);
_disable();
}
#endif
} while (DpcData->DpcQueueDepth != 0);
}
Generated on Sun May 27 2012 05:58:35 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.