-/*
+/* $Id: kill.c,v 1.46 2001/07/28 07:57:24 ea Exp $
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/kill.c
#include <internal/mm.h>
#include <internal/ob.h>
#include <internal/port.h>
+#include <internal/pool.h>
#define NDEBUG
#include <internal/debug.h>
VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
+#define TAG_TERMINATE_APC TAG('T', 'A', 'P', 'C')
+
/* FUNCTIONS *****************************************************************/
-VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
+VOID
+PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
{
KIRQL oldlvl;
PLIST_ENTRY current_entry;
current_entry = Process->ThreadListHead.Flink;
while (current_entry != &Process->ThreadListHead)
{
- current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.ProcessThreadListEntry);
- if (current != PsGetCurrentThread())
+ current = CONTAINING_RECORD(current_entry, ETHREAD,
+ Tcb.ProcessThreadListEntry);
+ if (current != PsGetCurrentThread() &&
+ current->DeadThread == 0)
{
- DPRINT("Terminating %x, current thread: %x, thread's process: %x\n", current, PsGetCurrentThread(), current->ThreadsProcess );
+ DPRINT("Terminating %x, current thread: %x, "
+ "thread's process: %x\n", current, PsGetCurrentThread(),
+ current->ThreadsProcess);
+ KeReleaseSpinLock(&PiThreadListLock, oldlvl);
PsTerminateOtherThread(current, ExitStatus);
+ KeAcquireSpinLock(&PiThreadListLock, &oldlvl);
+ current_entry = Process->ThreadListHead.Flink;
+ }
+ else
+ {
+ current_entry = current_entry->Flink;
}
- current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
DPRINT("Finished PiTerminateProcessThreads()\n");
}
-VOID PsReapThreads(VOID)
+VOID
+PsReapThreads(VOID)
{
PLIST_ENTRY current_entry;
PETHREAD current;
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
CurrentThread->ExitStatus = ExitStatus;
+ KeCancelTimer(&KeGetCurrentThread()->Timer);
KeAcquireDispatcherDatabaseLock(FALSE);
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
KeBugCheck(0);
}
-VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
+VOID
+PiTerminateThreadRundownRoutine(PKAPC Apc)
+{
+ ExFreePool(Apc);
+}
+
+VOID
+PiTerminateThreadKernelRoutine(PKAPC Apc,
+ PKNORMAL_ROUTINE* NormalRoutine,
+ PVOID* NormalContext,
+ PVOID* SystemArgument1,
+ PVOID* SystemArguemnt2)
+{
+ ExFreePool(Apc);
+}
+
+VOID
+PiTerminateThreadNormalRoutine(PVOID NormalContext,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2)
+{
+ PsTerminateCurrentThread(PsGetCurrentThread()->ExitStatus);
+}
+
+VOID
+PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
/*
* FUNCTION: Terminate a thread when calling from another thread's context
+ * NOTES: This function must be called with PiThreadListLock held
*/
{
- KIRQL oldIrql;
-
- DPRINT("PsTerminateOtherThread(Thread %x, ExitStatus %x)\n",
- Thread, ExitStatus);
-
- KeAcquireSpinLock( &PiThreadListLock, &oldIrql );
- Thread->DeadThread = 1;
- Thread->ExitStatus = ExitStatus;
- if( Thread->Tcb.State == THREAD_STATE_FROZEN && (Thread->Tcb.Alertable || Thread->Tcb.WaitMode == UserMode) )
- KeRemoveAllWaitsThread( Thread, STATUS_ALERTED );
- KeReleaseSpinLock( &PiThreadListLock, oldIrql );
+ PKAPC Apc;
+
+ DPRINT("PsTerminateOtherThread(Thread %x, ExitStatus %x)\n",
+ Thread, ExitStatus);
+
+ Thread->DeadThread = 1;
+ Thread->ExitStatus = ExitStatus;
+ Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC);
+ KeInitializeApc(Apc,
+ &Thread->Tcb,
+ 0,
+ PiTerminateThreadKernelRoutine,
+ PiTerminateThreadRundownRoutine,
+ PiTerminateThreadNormalRoutine,
+ KernelMode,
+ NULL);
+ KeInsertQueueApc(Apc,
+ NULL,
+ NULL,
+ KernelMode);
}
-NTSTATUS STDCALL PiTerminateProcess(PEPROCESS Process,
- NTSTATUS ExitStatus)
+NTSTATUS STDCALL
+PiTerminateProcess(PEPROCESS Process, NTSTATUS ExitStatus)
{
DPRINT("PiTerminateProcess(Process %x, ExitStatus %x) RC %d HC %d\n",
Process, ExitStatus, ObGetReferenceCount(Process),
ObGetHandleCount(Process));
- if (Process->Pcb.ProcessState == PROCESS_STATE_TERMINATED)
+ if (InterlockedExchange((PLONG)&Process->Pcb.State,
+ PROCESS_STATE_TERMINATED) ==
+ PROCESS_STATE_TERMINATED)
{
return(STATUS_SUCCESS);
}
-
+ KeAttachProcess( Process );
ObCloseAllHandles(Process);
+ KeDetachProcess();
KeAcquireDispatcherDatabaseLock(FALSE);
- Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;
Process->Pcb.DispatcherHeader.SignalState = TRUE;
KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
KeReleaseDispatcherDatabaseLock(FALSE);
- DPRINT("RC %d\n", ObGetReferenceCount(Process));
return(STATUS_SUCCESS);
}
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+ {
+ return(Status);
+ }
PiTerminateProcessThreads(Process, ExitStatus);
if (PsGetCurrentThread()->ThreadsProcess == Process)
return(STATUS_SUCCESS);
}
-NTSTATUS STDCALL NtCallTerminatePorts(PETHREAD Thread)
+NTSTATUS STDCALL
+NtCallTerminatePorts(PETHREAD Thread)
{
KIRQL oldIrql;
PLIST_ENTRY current_entry;
return(STATUS_SUCCESS);
}
-NTSTATUS STDCALL NtRegisterThreadTerminatePort(HANDLE TerminationPortHandle)
+NTSTATUS STDCALL
+NtRegisterThreadTerminatePort(HANDLE TerminationPortHandle)
{
NTSTATUS Status;
PEPORT_TERMINATION_REQUEST Request;