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();
Show replies by date