Used HasTerminated as bitmap for flags to make difference between calling PsTerminateCurrentThread and delivering an apc which calls PsTerminateCurrentThread. Modified: trunk/reactos/ntoskrnl/ps/kill.c _____
Modified: trunk/reactos/ntoskrnl/ps/kill.c --- trunk/reactos/ntoskrnl/ps/kill.c 2005-02-23 18:40:51 UTC (rev 13727) +++ trunk/reactos/ntoskrnl/ps/kill.c 2005-02-23 18:43:25 UTC (rev 13728) @@ -23,6 +23,9 @@
LIST_ENTRY ThreadsToReapHead;
+#define TERMINATE_PROC 0x1 +#define TERMINATE_APC 0x2 + /* FUNCTIONS *****************************************************************/
VOID @@ -110,9 +113,21 @@ SIZE_T Length = PAGE_SIZE; PVOID TebBlock;
+ DPRINT("PsTerminateCurrentThread(ExitStatus %x)\n", ExitStatus); + + CurrentThread = PsGetCurrentThread(); + + oldIrql = KeAcquireDispatcherDatabaseLock(); + if (CurrentThread->HasTerminated & TERMINATE_PROC) + { + KeReleaseDispatcherDatabaseLock(oldIrql); + return; + } + CurrentThread->HasTerminated |= TERMINATE_PROC; + KeReleaseDispatcherDatabaseLock(oldIrql); + KeLowerIrql(PASSIVE_LEVEL);
- CurrentThread = PsGetCurrentThread(); CurrentProcess = CurrentThread->ThreadsProcess;
/* Can't terminate a thread if it attached another process */ @@ -130,7 +145,6 @@
DPRINT("terminating %x\n",CurrentThread);
- CurrentThread->HasTerminated = TRUE; CurrentThread->ExitStatus = ExitStatus; KeQuerySystemTime((PLARGE_INTEGER)&CurrentThread->ExitTime);
@@ -238,13 +252,7 @@ PVOID SystemArgument1, PVOID SystemArgument2) { - PETHREAD EThread = PsGetCurrentThread(); - if (EThread->HasTerminated) - { - /* Someone else has already called PsTerminateCurrentThread */ - return; - } - PsTerminateCurrentThread(PsGetCurrentThread()->ExitStatus); + PsTerminateCurrentThread((NTSTATUS)SystemArgument1); }
VOID @@ -262,14 +270,13 @@ Thread, ExitStatus);
OldIrql = KeAcquireDispatcherDatabaseLock(); - if (Thread->HasTerminated) + if (Thread->HasTerminated & TERMINATE_APC) { KeReleaseDispatcherDatabaseLock (OldIrql); return; } - Thread->HasTerminated = TRUE; + Thread->HasTerminated |= TERMINATE_APC; KeReleaseDispatcherDatabaseLock (OldIrql); - Thread->ExitStatus = ExitStatus; Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC); KeInitializeApc(Apc, &Thread->Tcb, @@ -280,8 +287,8 @@ KernelMode, NULL); KeInsertQueueApc(Apc, + (PVOID)ExitStatus, NULL, - NULL, IO_NO_INCREMENT);
OldIrql = KeAcquireDispatcherDatabaseLock();