diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 98ce792f6d1..7fe870f2685 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -50,7 +50,7 @@ VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type, ULONG Size, ULONG SignalState); VOID KeDumpStackFrames(PULONG Frame); BOOLEAN KiTestAlert(VOID); -VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus); +VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus, BOOL Unblock); PULONG KeGetStackTopThread(struct _ETHREAD* Thread); VOID KeContextToTrapFrame(PCONTEXT Context, PKTRAP_FRAME TrapFrame); diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index d041485c2fa..b490d71aa6b 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -373,7 +373,7 @@ KeInsertQueueApc (PKAPC Apc, Apc->NormalRoutine == NULL) { KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb), - STATUS_KERNEL_APC); + STATUS_KERNEL_APC, TRUE); } /* @@ -390,7 +390,7 @@ KeInsertQueueApc (PKAPC Apc, PETHREAD Thread; Thread = CONTAINING_RECORD(TargetThread, ETHREAD, Tcb); - KeRemoveAllWaitsThread(Thread, STATUS_USER_APC); + KeRemoveAllWaitsThread(Thread, STATUS_USER_APC, TRUE); } } @@ -409,7 +409,7 @@ KeInsertQueueApc (PKAPC Apc, Status = STATUS_USER_APC; TargetThread->Alerted[0] = 1; KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb), - STATUS_USER_APC); + STATUS_USER_APC, TRUE); } KeReleaseSpinLock(&PiApcLock, oldlvl); return TRUE; diff --git a/reactos/ntoskrnl/ke/i386/tskswitch.S b/reactos/ntoskrnl/ke/i386/tskswitch.S index b09efa67ba4..7c94ad6872b 100644 --- a/reactos/ntoskrnl/ke/i386/tskswitch.S +++ b/reactos/ntoskrnl/ke/i386/tskswitch.S @@ -144,6 +144,14 @@ _Ki386ContextSwitch: */ sti + push $_PiThreadListLock + call _KeReleaseSpinLockFromDpcLevel@4 + + cmpl $0, _PiNrThreadsAwaitingReaping + je .L3 + call _PiWakeupReaperThread@0 +.L3: + /* * Restore the saved register and exit */ diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 51394a3224c..36d2ea8d1af 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -188,9 +188,9 @@ KiIsObjectSignalled(DISPATCHER_HEADER * hdr, } } -VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus) +VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus, BOOL Unblock) { - PKWAIT_BLOCK WaitBlock; + PKWAIT_BLOCK WaitBlock, PrevWaitBlock; BOOLEAN WasWaiting = FALSE; KeAcquireDispatcherDatabaseLock(FALSE); @@ -202,12 +202,18 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus) } while (WaitBlock != NULL) { - RemoveEntryList(&WaitBlock->WaitListEntry); + if (WaitBlock->WaitListEntry.Flink != NULL && WaitBlock->WaitListEntry.Blink != NULL) + { + RemoveEntryList (&WaitBlock->WaitListEntry); + WaitBlock->WaitListEntry.Flink = WaitBlock->WaitListEntry.Blink = NULL; + } + PrevWaitBlock = WaitBlock; WaitBlock = WaitBlock->NextWaitBlock; + PrevWaitBlock->NextWaitBlock = NULL; } Thread->Tcb.WaitBlockList = NULL; - if (WasWaiting) + if (WasWaiting && Unblock) { PsUnblockThread(Thread, &WaitStatus); } @@ -243,6 +249,7 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr, WaiterHead = CONTAINING_RECORD(EnumEntry, KWAIT_BLOCK, WaitListEntry); DPRINT("current_entry %x current %x\n", EnumEntry, WaiterHead); EnumEntry = EnumEntry->Flink; + assert(WaiterHead->Thread != NULL); assert(WaiterHead->Thread->WaitBlockList != NULL); Abandoned = FALSE; @@ -252,7 +259,11 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr, DPRINT("WaitAny: Remove all wait blocks.\n"); for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock) { - RemoveEntryList(&Waiter->WaitListEntry); + if (Waiter->WaitListEntry.Flink != NULL && Waiter->WaitListEntry.Blink != NULL) + { + RemoveEntryList(&Waiter->WaitListEntry); + Waiter->WaitListEntry.Flink = Waiter->WaitListEntry.Blink = NULL; + } } WaiterHead->Thread->WaitBlockList = NULL; @@ -287,8 +298,12 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr, { for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock) { - RemoveEntryList(&Waiter->WaitListEntry); - + if (Waiter->WaitListEntry.Flink != NULL && Waiter->WaitListEntry.Blink != NULL) + { + RemoveEntryList(&Waiter->WaitListEntry); + Waiter->WaitListEntry.Flink = Waiter->WaitListEntry.Blink = NULL; + } + if (Waiter->WaitType == WaitAll) { Abandoned = KiSideEffectsBeforeWake(Waiter->Object, Waiter->Thread) @@ -488,7 +503,7 @@ KeWaitForMultipleObjects(ULONG Count, { KeAcquireDispatcherDatabaseLock(FALSE); - /* + /* * If we are going to wait alertably and a user apc is pending * then return */ diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index 08ee4332458..2cd2556444a 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -1,4 +1,4 @@ -/* $Id: kill.c,v 1.62 2003/07/21 21:53:53 royce Exp $ +/* $Id: kill.c,v 1.63 2003/08/18 11:23:32 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -158,10 +158,11 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus) PLIST_ENTRY current_entry; PKMUTANT Mutant; - CurrentThread = PsGetCurrentThread(); DPRINT("terminating %x\n",CurrentThread); KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + + CurrentThread = PsGetCurrentThread(); CurrentThread->ExitStatus = ExitStatus; Thread = KeGetCurrentThread(); @@ -180,15 +181,18 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus) FALSE); current_entry = Thread->MutantListHead.Flink; } + + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); KeAcquireDispatcherDatabaseLock(FALSE); CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE; KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); - KeReleaseDispatcherDatabaseLock(FALSE); + KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE); + + KeRemoveAllWaitsThread (CurrentThread, STATUS_UNSUCCESSFUL, FALSE); - KeAcquireSpinLock(&PiThreadListLock, &oldIrql); PsDispatchThreadNoLock(THREAD_STATE_TERMINATED_1); -DPRINT1("Unexpected return, CurrentThread %x PsGetCurrentThread() %x\n", CurrentThread, PsGetCurrentThread()); + DPRINT1("Unexpected return, CurrentThread %x PsGetCurrentThread() %x\n", CurrentThread, PsGetCurrentThread()); KEBUGCHECK(0); }