{
PNDIS_MINIPORT_TIMER CurrentTimer;
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
if (!Timer->Miniport->TimerQueue)
return FALSE;
* - 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
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);
+ }
}
\f
*/
{
LARGE_INTEGER Timeout;
+ KIRQL OldIrql;
ASSERT_IRQL(DISPATCH_LEVEL);
ASSERT(Timer);
/* 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);
}
\f
*/
{
LARGE_INTEGER Timeout;
+ KIRQL OldIrql;
ASSERT_IRQL(DISPATCH_LEVEL);
ASSERT(Timer);
/* 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);
}
\f