[WIN32CSR] Clean up the debris from r47314: Removed some redundant code, reorganized...
[reactos.git] / reactos / subsystems / win32 / csrss / csrsrv / thredsup.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS CSR Sub System
4 * FILE: subsys/csr/csrsrv/procsup.c
5 * PURPOSE: CSR Process Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 * Alex Ionescu
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include <srv.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17 #define LOCK RtlEnterCriticalSection(&ProcessDataLock)
18 #define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
19 #define CsrHeap RtlGetProcessHeap()
20 #define CsrHashThread(t) \
21 (HandleToUlong(t)&(256 - 1))
22
23 #define CsrAcquireProcessLock() LOCK
24 #define CsrReleaseProcessLock() UNLOCK
25
26 /* GLOBALS ********************************************************************/
27
28 LIST_ENTRY CsrThreadHashTable[256];
29 extern PCSRSS_PROCESS_DATA CsrRootProcess;
30 extern RTL_CRITICAL_SECTION ProcessDataLock;
31 extern PCSRSS_PROCESS_DATA ProcessData[256];
32
33 /* FUNCTIONS ******************************************************************/
34
35 PCSR_THREAD
36 NTAPI
37 CsrAllocateThread(IN PCSRSS_PROCESS_DATA CsrProcess)
38 {
39 PCSR_THREAD CsrThread;
40
41 /* Allocate the structure */
42 CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD));
43 if (!CsrThread) return(NULL);
44
45 /* Reference the Thread and Process */
46 CsrThread->ReferenceCount++;
47 // CsrProcess->ReferenceCount++;
48
49 /* Set the Parent Process */
50 CsrThread->Process = CsrProcess;
51
52 /* Return Thread */
53 return CsrThread;
54 }
55
56 PCSR_THREAD
57 NTAPI
58 CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL,
59 IN PCLIENT_ID ClientId)
60 {
61 ULONG i;
62 PLIST_ENTRY ListHead, NextEntry;
63 PCSR_THREAD FoundThread;
64
65 /* Hash the Thread */
66 i = CsrHashThread(ClientId->UniqueThread);
67
68 /* Set the list pointers */
69 ListHead = &CsrThreadHashTable[i];
70 NextEntry = ListHead->Flink;
71
72 /* Star the loop */
73 while (NextEntry != ListHead)
74 {
75 /* Get the thread */
76 FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
77
78 /* Compare the CID */
79 if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread)
80 {
81 /* Match found, return the process */
82 *Process = FoundThread->Process;
83
84 /* Return thread too */
85 // DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process);
86 return FoundThread;
87 }
88
89 /* Next */
90 NextEntry = NextEntry->Flink;
91 }
92
93 /* Nothing found */
94 return NULL;
95 }
96
97 PCSR_THREAD
98 NTAPI
99 CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL,
100 IN PCLIENT_ID Cid)
101 {
102 PLIST_ENTRY ListHead, NextEntry;
103 PCSR_THREAD FoundThread = NULL;
104
105 /* Use the Root Process if none was specified */
106 if (!CsrProcess) CsrProcess = CsrRootProcess;
107
108 /* Save the List pointers */
109 // DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount);
110 ListHead = &CsrProcess->ThreadList;
111 NextEntry = ListHead->Flink;
112
113 /* Start the Loop */
114 while (NextEntry != ListHead)
115 {
116 /* Get Thread Entry */
117 FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
118
119 /* Check for TID Match */
120 if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break;
121
122 /* Next entry */
123 NextEntry = NextEntry->Flink;
124 }
125
126 /* Return what we found */
127 // DPRINT1("Found: %p\n", FoundThread);
128 return FoundThread;
129 }
130
131 VOID
132 NTAPI
133 CsrInsertThread(IN PCSRSS_PROCESS_DATA Process,
134 IN PCSR_THREAD Thread)
135 {
136 ULONG i;
137
138 /* Insert it into the Regular List */
139 InsertTailList(&Process->ThreadList, &Thread->Link);
140
141 /* Increase Thread Count */
142 Process->ThreadCount++;
143
144 /* Hash the Thread */
145 i = CsrHashThread(Thread->ClientId.UniqueThread);
146 // DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i);
147
148 /* Insert it there too */
149 InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks);
150 }
151
152 VOID
153 NTAPI
154 CsrDeallocateThread(IN PCSR_THREAD CsrThread)
155 {
156 /* Free the process object from the heap */
157 RtlFreeHeap(CsrHeap, 0, CsrThread);
158 }
159
160 VOID
161 NTAPI
162 CsrRemoveThread(IN PCSR_THREAD CsrThread)
163 {
164 /* Remove it from the List */
165 RemoveEntryList(&CsrThread->Link);
166
167 /* Decreate the thread count of the process */
168 CsrThread->Process->ThreadCount--;
169
170 /* Remove it from the Hash List as well */
171 if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks);
172
173 /* Check if this is the last Thread */
174 if (!CsrThread->Process->ThreadCount)
175 {
176 /* Check if it's not already been marked for deletion */
177 if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated))
178 {
179 /* Let everyone know this process is about to lose the thread */
180 //CsrThread->Process->Flags |= CsrProcessLastThreadTerminated;
181
182 /* Reference the Process */
183 //CsrLockedDereferenceProcess(CsrThread->Process);
184 }
185 }
186
187 /* Mark the thread for deletion */
188 CsrThread->Flags |= CsrThreadInTermination;
189 }
190
191 VOID
192 NTAPI
193 CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)
194 {
195 /* Remove this thread */
196 CsrRemoveThread(CsrThread);
197
198 /* Release the Process Lock */
199 //CsrReleaseProcessLock();
200
201 /* Close the NT Thread Handle */
202 if (CsrThread->ThreadHandle) NtClose(CsrThread->ThreadHandle);
203
204 /* De-allocate the CSR Thread Object */
205 CsrDeallocateThread(CsrThread);
206
207 /* Remove a reference from the process */
208 //CsrDereferenceProcess(CsrProcess);
209 }
210
211 NTSTATUS
212 NTAPI
213 CsrCreateThread(IN PCSRSS_PROCESS_DATA CsrProcess,
214 IN HANDLE hThread,
215 IN PCLIENT_ID ClientId)
216 {
217 NTSTATUS Status;
218 PCSR_THREAD CsrThread;
219 //PCSRSS_PROCESS_DATA CurrentProcess;
220 PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
221 CLIENT_ID CurrentCid;
222 KERNEL_USER_TIMES KernelTimes;
223
224 // DPRINT1("CSRSRV: %s called\n", __FUNCTION__);
225
226 /* Get the current thread and CID */
227 CurrentCid = CurrentThread->ClientId;
228 // DPRINT1("CALLER PID/TID: %lx/%lx\n", CurrentCid.UniqueProcess, CurrentCid.UniqueThread);
229
230 /* Acquire the Process Lock */
231 CsrAcquireProcessLock();
232 #if 0
233 /* Get the current Process and make sure the Thread is valid with this CID */
234 CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
235 &CurrentCid);
236
237 /* Something is wrong if we get an empty thread back */
238 if (!CurrentThread)
239 {
240 DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
241 CsrReleaseProcessLock();
242 return STATUS_THREAD_IS_TERMINATING;
243 }
244 #endif
245 /* Get the Thread Create Time */
246 Status = NtQueryInformationThread(hThread,
247 ThreadTimes,
248 (PVOID)&KernelTimes,
249 sizeof(KernelTimes),
250 NULL);
251
252 /* Allocate a CSR Thread Structure */
253 if (!(CsrThread = CsrAllocateThread(CsrProcess)))
254 {
255 DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
256 CsrReleaseProcessLock();
257 return STATUS_NO_MEMORY;
258 }
259
260 /* Save the data we have */
261 CsrThread->CreateTime = KernelTimes.CreateTime;
262 CsrThread->ClientId = *ClientId;
263 CsrThread->ThreadHandle = hThread;
264 CsrThread->Flags = 0;
265
266 /* Insert the Thread into the Process */
267 CsrInsertThread(CsrProcess, CsrThread);
268
269 /* Release the lock and return */
270 CsrReleaseProcessLock();
271 return STATUS_SUCCESS;
272 }
273
274 PCSR_THREAD
275 NTAPI
276 CsrAddStaticServerThread(IN HANDLE hThread,
277 IN PCLIENT_ID ClientId,
278 IN ULONG ThreadFlags)
279 {
280 PCSR_THREAD CsrThread;
281
282 /* Get the Lock */
283 CsrAcquireProcessLock();
284
285 /* Allocate the Server Thread */
286 if ((CsrThread = CsrAllocateThread(CsrRootProcess)))
287 {
288 /* Setup the Object */
289 // DPRINT1("New CSR thread created: %lx PID/TID: %lx/%lx\n", CsrThread, ClientId->UniqueProcess, ClientId->UniqueThread);
290 CsrThread->ThreadHandle = hThread;
291 CsrThread->ClientId = *ClientId;
292 CsrThread->Flags = ThreadFlags;
293
294 /* Insert it into the Thread List */
295 InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link);
296
297 /* Increment the thread count */
298 CsrRootProcess->ThreadCount++;
299 }
300
301 /* Release the Process Lock and return */
302 CsrReleaseProcessLock();
303 return CsrThread;
304 }
305
306 /* EOF */