mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-29 12:23:30 +00:00
[NDIS]
- Hold the miniport lock when we work with the timer queue - Use the return value of KeSetTimer(Ex) to determine whether we need to queue the timer in our queue, otherwise we just use the entry that is already there - Add more assertions svn path=/trunk/; revision=47642
This commit is contained in:
@@ -99,6 +99,8 @@ BOOLEAN DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer)
|
||||
{
|
||||
PNDIS_MINIPORT_TIMER CurrentTimer;
|
||||
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
|
||||
if (!Timer->Miniport->TimerQueue)
|
||||
return FALSE;
|
||||
|
||||
@@ -143,13 +145,21 @@ NdisMCancelTimer(
|
||||
* - call at IRQL <= DISPATCH_LEVEL
|
||||
*/
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
||||
ASSERT(TimerCancelled);
|
||||
ASSERT(Timer);
|
||||
|
||||
*TimerCancelled = KeCancelTimer (&Timer->Timer);
|
||||
|
||||
DequeueMiniportTimer(Timer);
|
||||
if (*TimerCancelled)
|
||||
{
|
||||
KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql);
|
||||
/* If it's somebody already dequeued it, something is wrong (maybe a double-cancel?) */
|
||||
if (!DequeueMiniportTimer(Timer)) ASSERT(FALSE);
|
||||
KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql);
|
||||
}
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
@@ -166,7 +176,13 @@ MiniTimerDpcFunction(PKDPC Dpc,
|
||||
SystemArgument2);
|
||||
|
||||
/* Only dequeue if the timer has a period of 0 */
|
||||
if (!Timer->Timer.Period) DequeueMiniportTimer(Timer);
|
||||
if (!Timer->Timer.Period)
|
||||
{
|
||||
KeAcquireSpinLockAtDpcLevel(&Timer->Miniport->Lock);
|
||||
/* If someone already dequeued it, something is wrong (borked timer implementation?) */
|
||||
if (!DequeueMiniportTimer(Timer)) ASSERT(FALSE);
|
||||
KeReleaseSpinLockFromDpcLevel(&Timer->Miniport->Lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -224,6 +240,7 @@ NdisMSetPeriodicTimer(
|
||||
*/
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
KIRQL OldIrql;
|
||||
|
||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
||||
ASSERT(Timer);
|
||||
@@ -231,14 +248,15 @@ NdisMSetPeriodicTimer(
|
||||
/* relative delays are negative, absolute are positive; resolution is 100ns */
|
||||
Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000);
|
||||
|
||||
/* Dequeue the timer if it is queued already */
|
||||
DequeueMiniportTimer(Timer);
|
||||
|
||||
/* Add the timer at the head of the timer queue */
|
||||
Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
|
||||
Timer->Miniport->TimerQueue = Timer;
|
||||
|
||||
KeSetTimerEx (&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc);
|
||||
KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql);
|
||||
/* If KeSetTimer(Ex) returns FALSE then the timer is not in the system's queue (and not in ours either) */
|
||||
if (!KeSetTimerEx(&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc))
|
||||
{
|
||||
/* Add the timer at the head of the timer queue */
|
||||
Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
|
||||
Timer->Miniport->TimerQueue = Timer;
|
||||
}
|
||||
KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql);
|
||||
}
|
||||
|
||||
|
||||
@@ -262,6 +280,7 @@ NdisMSetTimer(
|
||||
*/
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
KIRQL OldIrql;
|
||||
|
||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
||||
ASSERT(Timer);
|
||||
@@ -269,14 +288,15 @@ NdisMSetTimer(
|
||||
/* relative delays are negative, absolute are positive; resolution is 100ns */
|
||||
Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000);
|
||||
|
||||
/* Dequeue the timer if it is queued already */
|
||||
DequeueMiniportTimer(Timer);
|
||||
|
||||
/* Add the timer at the head of the timer queue */
|
||||
Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
|
||||
Timer->Miniport->TimerQueue = Timer;
|
||||
|
||||
KeSetTimer (&Timer->Timer, Timeout, &Timer->Dpc);
|
||||
KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql);
|
||||
/* If KeSetTimer(Ex) returns FALSE then the timer is not in the system's queue (and not in ours either) */
|
||||
if (!KeSetTimer(&Timer->Timer, Timeout, &Timer->Dpc))
|
||||
{
|
||||
/* Add the timer at the head of the timer queue */
|
||||
Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
|
||||
Timer->Miniport->TimerQueue = Timer;
|
||||
}
|
||||
KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user