mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 04:13:33 +00:00
- Fixed the broken implementation of KeFlushQueueApc.
- Fixed some locking operations with two spin locks. svn path=/trunk/; revision=16752
This commit is contained in:
+22
-29
@@ -270,14 +270,14 @@ KiInsertQueueApc(PKAPC Apc,
|
||||
*/
|
||||
if ((Apc->ApcMode != KernelMode) && (Apc->KernelRoutine == (PKKERNEL_ROUTINE)PsExitSpecialApc)) {
|
||||
|
||||
DPRINT1("Inserting the Process Exit APC into the Queue\n");
|
||||
DPRINT1("Inserting the Thread Exit APC for '%.16s' into the Queue\n", ((PETHREAD)Thread)->ThreadsProcess->ImageFileName);
|
||||
Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = TRUE;
|
||||
InsertHeadList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
|
||||
&Apc->ApcListEntry);
|
||||
|
||||
} else if (Apc->NormalRoutine == NULL) {
|
||||
|
||||
DPRINT("Inserting Special APC %x into the Queue\n", Apc);
|
||||
DPRINT("Inserting Special APC %x for '%.16s' into the Queue\n", Apc, ((PETHREAD)Thread)->ThreadsProcess->ImageFileName);
|
||||
|
||||
for (ApcListEntry = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode].Flink;
|
||||
ApcListEntry != &Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode];
|
||||
@@ -293,7 +293,7 @@ KiInsertQueueApc(PKAPC Apc,
|
||||
|
||||
} else {
|
||||
|
||||
DPRINT("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode);
|
||||
DPRINT("Inserting Normal APC %x for '%.16s' into the %x Queue\n", Apc, ((PETHREAD)Thread)->ThreadsProcess->ImageFileName, Apc->ApcMode);
|
||||
InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
|
||||
&Apc->ApcListEntry);
|
||||
}
|
||||
@@ -473,34 +473,27 @@ KeFlushQueueApc(IN PKTHREAD Thread,
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
|
||||
|
||||
/* Check if the list is empty */
|
||||
if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode]))
|
||||
ApcEntry = CurrentEntry = NULL;
|
||||
while (!IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode]))
|
||||
{
|
||||
/* We'll return NULL */
|
||||
ApcEntry = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove this one */
|
||||
RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]);
|
||||
CurrentEntry = ApcEntry;
|
||||
if (ApcEntry == NULL)
|
||||
{
|
||||
ApcEntry = CurrentEntry = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentEntry->Flink = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]);
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
CurrentEntry->Flink = NULL;
|
||||
|
||||
/* Remove all the other ones too, if present */
|
||||
do
|
||||
{
|
||||
/* Get the APC */
|
||||
Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
|
||||
|
||||
/* Move to the next one */
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
|
||||
/* Mark it as not inserted */
|
||||
Apc->Inserted = FALSE;
|
||||
} while (ApcEntry != CurrentEntry);
|
||||
/* Get the APC */
|
||||
Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
|
||||
Apc->Inserted = FALSE;
|
||||
}
|
||||
|
||||
/* Release the locks */
|
||||
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
|
||||
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
||||
/* Return the first entry */
|
||||
@@ -539,7 +532,7 @@ KeRemoveQueueApc(PKAPC Apc)
|
||||
DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
|
||||
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
|
||||
|
||||
/* Check if it's inserted */
|
||||
if (Apc->Inserted) {
|
||||
@@ -565,13 +558,13 @@ KeRemoveQueueApc(PKAPC Apc)
|
||||
} else {
|
||||
|
||||
/* It's not inserted, fail */
|
||||
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
|
||||
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Restore IRQL and Return */
|
||||
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
|
||||
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
+22
-26
@@ -213,7 +213,7 @@ PspExitThread(NTSTATUS ExitStatus)
|
||||
PTERMINATION_PORT TerminationPort;
|
||||
PTEB Teb;
|
||||
KIRQL oldIrql;
|
||||
PLIST_ENTRY ApcEntry, CurrentApc;
|
||||
PLIST_ENTRY ApcEntry;
|
||||
PKAPC Apc;
|
||||
|
||||
DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
|
||||
@@ -338,30 +338,26 @@ PspExitThread(NTSTATUS ExitStatus)
|
||||
KeDisableThreadApcQueueing(&CurrentThread->Tcb);
|
||||
|
||||
/* Flush the User APCs */
|
||||
if ((ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode)))
|
||||
ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode);
|
||||
while(ApcEntry)
|
||||
{
|
||||
CurrentApc = ApcEntry;
|
||||
do
|
||||
{
|
||||
/* Get the APC */
|
||||
Apc = CONTAINING_RECORD(CurrentApc, KAPC, ApcListEntry);
|
||||
/* Get the APC */
|
||||
Apc = CONTAINING_RECORD(ApcEntry, KAPC, ApcListEntry);
|
||||
|
||||
/* Move to the next one */
|
||||
CurrentApc = CurrentApc->Flink;
|
||||
/* Move to the next one */
|
||||
ApcEntry = ApcEntry->Flink;
|
||||
|
||||
/* Rundown the APC or de-allocate it */
|
||||
if (Apc->RundownRoutine)
|
||||
{
|
||||
/* Call its own routine */
|
||||
(Apc->RundownRoutine)(Apc);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do it ourselves */
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
}
|
||||
while (CurrentApc != ApcEntry);
|
||||
/* Rundown the APC or de-allocate it */
|
||||
if (Apc->RundownRoutine)
|
||||
{
|
||||
/* Call its own routine */
|
||||
(Apc->RundownRoutine)(Apc);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do it ourselves */
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Call the Lego routine */
|
||||
@@ -392,8 +388,8 @@ PsExitSpecialApc(PKAPC Apc,
|
||||
PVOID* SystemArgument1,
|
||||
PVOID* SystemArguemnt2)
|
||||
{
|
||||
DPRINT1("PsExitSpecialApc called: 0x%x (proc: 0x%x)\n",
|
||||
PsGetCurrentThread(), PsGetCurrentProcess());
|
||||
DPRINT1("PsExitSpecialApc called: 0x%x (proc: 0x%x, '%.16s')\n",
|
||||
PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
|
||||
|
||||
/* Don't do anything unless we are in User-Mode */
|
||||
if (Apc->SystemArgument2)
|
||||
@@ -421,8 +417,8 @@ PspExitNormalApc(PVOID NormalContext,
|
||||
PETHREAD Thread = PsGetCurrentThread();
|
||||
NTSTATUS ExitStatus;
|
||||
|
||||
DPRINT1("PspExitNormalApc called: 0x%x (proc: 0x%x)\n",
|
||||
PsGetCurrentThread(), PsGetCurrentProcess());
|
||||
DPRINT1("PspExitNormalApc called: 0x%x (proc: 0x%x, '%.16s')\n",
|
||||
PsGetCurrentThread(), PsGetCurrentProcess(), PsGetCurrentProcess()->ImageFileName);
|
||||
|
||||
/* This should never happen */
|
||||
ASSERT(!SystemArgument2);
|
||||
|
||||
Reference in New Issue
Block a user