Used HasTerminated as bitmap for flags to make difference between calling PsTerminateCurrentThread and delivering an apc which calls PsTerminateCurrentThread.

svn path=/trunk/; revision=13728
This commit is contained in:
Hartmut Birr 2005-02-23 18:43:25 +00:00
parent 6e837055bc
commit 3d2a023ce8

View file

@ -23,6 +23,9 @@ NTSTATUS STDCALL NtCallTerminatePorts(PETHREAD Thread);
LIST_ENTRY ThreadsToReapHead; LIST_ENTRY ThreadsToReapHead;
#define TERMINATE_PROC 0x1
#define TERMINATE_APC 0x2
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID VOID
@ -110,9 +113,21 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
SIZE_T Length = PAGE_SIZE; SIZE_T Length = PAGE_SIZE;
PVOID TebBlock; PVOID TebBlock;
KeLowerIrql(PASSIVE_LEVEL); DPRINT("PsTerminateCurrentThread(ExitStatus %x)\n", ExitStatus);
CurrentThread = PsGetCurrentThread(); CurrentThread = PsGetCurrentThread();
oldIrql = KeAcquireDispatcherDatabaseLock();
if (CurrentThread->HasTerminated & TERMINATE_PROC)
{
KeReleaseDispatcherDatabaseLock(oldIrql);
return;
}
CurrentThread->HasTerminated |= TERMINATE_PROC;
KeReleaseDispatcherDatabaseLock(oldIrql);
KeLowerIrql(PASSIVE_LEVEL);
CurrentProcess = CurrentThread->ThreadsProcess; CurrentProcess = CurrentThread->ThreadsProcess;
/* Can't terminate a thread if it attached another process */ /* Can't terminate a thread if it attached another process */
@ -130,7 +145,6 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
DPRINT("terminating %x\n",CurrentThread); DPRINT("terminating %x\n",CurrentThread);
CurrentThread->HasTerminated = TRUE;
CurrentThread->ExitStatus = ExitStatus; CurrentThread->ExitStatus = ExitStatus;
KeQuerySystemTime((PLARGE_INTEGER)&CurrentThread->ExitTime); KeQuerySystemTime((PLARGE_INTEGER)&CurrentThread->ExitTime);
@ -238,13 +252,7 @@ PiTerminateThreadNormalRoutine(PVOID NormalContext,
PVOID SystemArgument1, PVOID SystemArgument1,
PVOID SystemArgument2) PVOID SystemArgument2)
{ {
PETHREAD EThread = PsGetCurrentThread(); PsTerminateCurrentThread((NTSTATUS)SystemArgument1);
if (EThread->HasTerminated)
{
/* Someone else has already called PsTerminateCurrentThread */
return;
}
PsTerminateCurrentThread(PsGetCurrentThread()->ExitStatus);
} }
VOID VOID
@ -262,14 +270,13 @@ PsTerminateOtherThread(PETHREAD Thread,
Thread, ExitStatus); Thread, ExitStatus);
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
if (Thread->HasTerminated) if (Thread->HasTerminated & TERMINATE_APC)
{ {
KeReleaseDispatcherDatabaseLock (OldIrql); KeReleaseDispatcherDatabaseLock (OldIrql);
return; return;
} }
Thread->HasTerminated = TRUE; Thread->HasTerminated |= TERMINATE_APC;
KeReleaseDispatcherDatabaseLock (OldIrql); KeReleaseDispatcherDatabaseLock (OldIrql);
Thread->ExitStatus = ExitStatus;
Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC); Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC);
KeInitializeApc(Apc, KeInitializeApc(Apc,
&Thread->Tcb, &Thread->Tcb,
@ -280,7 +287,7 @@ PsTerminateOtherThread(PETHREAD Thread,
KernelMode, KernelMode,
NULL); NULL);
KeInsertQueueApc(Apc, KeInsertQueueApc(Apc,
NULL, (PVOID)ExitStatus,
NULL, NULL,
IO_NO_INCREMENT); IO_NO_INCREMENT);