Began converting minix fsd to work with new caching mechanism
[reactos.git] / reactos / ntoskrnl / ps / kill.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ps/kill.c
5 * PURPOSE: Terminating a thread
6 * PROGRAMMER: David Welch (welch@cwcom.net)
7 * UPDATE HISTORY:
8 * Created 22/05/98
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/ps.h>
15 #include <internal/ke.h>
16 #include <internal/mm.h>
17 #include <internal/ob.h>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22 /* GLOBALS *******************************************************************/
23
24 extern ULONG PiNrThreads;
25 extern ULONG PiNrRunnableThreads;
26 extern KSPIN_LOCK PiThreadListLock;
27
28 /* FUNCTIONS *****************************************************************/
29
30 VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
31 /*
32 * FUNCTION: Terminates the current thread
33 */
34 {
35 KIRQL oldlvl;
36 PETHREAD CurrentThread;
37
38 PiNrThreads--;
39
40 CurrentThread = PsGetCurrentThread();
41
42 CurrentThread->ExitStatus = ExitStatus;
43
44 DPRINT("terminating %x\n",CurrentThread);
45 ObDereferenceObject(CurrentThread->ThreadsProcess);
46 CurrentThread->ThreadsProcess = NULL;
47 KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
48
49 ObDereferenceObject(CurrentThread);
50 DPRINT("ObGetReferenceCount(CurrentThread) %d\n",
51 ObGetReferenceCount(CurrentThread));
52
53 CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
54 KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
55
56 PsDispatchThread(THREAD_STATE_TERMINATED);
57 KeBugCheck(0);
58 }
59
60 VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
61 /*
62 * FUNCTION: Terminate a thread when calling from that thread's context
63 */
64 {
65 KIRQL oldIrql;
66
67 KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
68 PiNrThreads--;
69 if (Thread->Tcb.State == THREAD_STATE_RUNNABLE)
70 {
71 PiNrRunnableThreads--;
72 RemoveEntryList(&Thread->Tcb.QueueListEntry);
73 }
74 Thread->Tcb.State = THREAD_STATE_TERMINATED;
75 Thread->Tcb.DispatcherHeader.SignalState = TRUE;
76 KeDispatcherObjectWake(&Thread->Tcb.DispatcherHeader);
77 ObDereferenceObject(Thread->ThreadsProcess);
78 ObDereferenceObject(Thread);
79 Thread->ThreadsProcess = NULL;
80 KeReleaseSpinLock(&PiThreadListLock, oldIrql);
81 }
82
83 NTSTATUS STDCALL PiTerminateProcess(PEPROCESS Process,
84 NTSTATUS ExitStatus)
85 {
86 KIRQL oldlvl;
87
88 DPRINT("PsTerminateProcess(Process %x, ExitStatus %x)\n",
89 Process, ExitStatus);
90
91 PiTerminateProcessThreads(Process, ExitStatus);
92 KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
93 Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;
94 Process->Pcb.DispatcherHeader.SignalState = TRUE;
95 KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
96 KeLowerIrql(oldlvl);
97 return(STATUS_SUCCESS);
98 }
99
100 NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,
101 IN NTSTATUS ExitStatus)
102 {
103 NTSTATUS Status;
104 PEPROCESS Process;
105
106 DPRINT("NtTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
107 ProcessHandle, ExitStatus);
108
109 Status = ObReferenceObjectByHandle(ProcessHandle,
110 PROCESS_TERMINATE,
111 PsProcessType,
112 UserMode,
113 (PVOID*)&Process,
114 NULL);
115 if (Status != STATUS_SUCCESS)
116 {
117 return(Status);
118 }
119
120 PiTerminateProcess(Process, ExitStatus);
121 if (PsGetCurrentThread()->ThreadsProcess == Process)
122 {
123 ObDereferenceObject(Process);
124 PsTerminateCurrentThread(ExitStatus);
125 }
126 ObDereferenceObject(Process);
127 return(STATUS_SUCCESS);
128 }
129
130
131 NTSTATUS STDCALL NtTerminateThread(IN HANDLE ThreadHandle,
132 IN NTSTATUS ExitStatus)
133 {
134 PETHREAD Thread;
135 NTSTATUS Status;
136
137 Status = ObReferenceObjectByHandle(ThreadHandle,
138 THREAD_TERMINATE,
139 PsThreadType,
140 UserMode,
141 (PVOID*)&Thread,
142 NULL);
143 if (Status != STATUS_SUCCESS)
144 {
145 return(Status);
146 }
147
148 if (Thread == PsGetCurrentThread())
149 {
150 PsTerminateCurrentThread(ExitStatus);
151 }
152 else
153 {
154 PsTerminateOtherThread(Thread, ExitStatus);
155 }
156 return(STATUS_SUCCESS);
157 }
158
159
160 NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
161 /*
162 * FUNCTION: Terminates the current thread
163 * ARGUMENTS:
164 * ExitStatus = Status to pass to the creater
165 * RETURNS: Doesn't
166 */
167 {
168 PsTerminateCurrentThread(ExitStatus);
169 return(STATUS_SUCCESS);
170 }
171
172
173 NTSTATUS STDCALL NtRegisterThreadTerminatePort(HANDLE TerminationPort)
174 {
175 UNIMPLEMENTED;
176 }