2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Client/Server Runtime SubSystem
4 * FILE: subsystems/win32/csrsrv/thredsup.c
5 * PURPOSE: CSR Server DLL Thread Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 * Alex Ionescu (alex@relsoft.net)
10 /* INCLUDES *******************************************************************/
17 #define CsrHashThread(t) \
18 (HandleToUlong(t)&(256 - 1))
20 /* GLOBALS ********************************************************************/
22 LIST_ENTRY CsrThreadHashTable
[256];
25 /* PRIVATE FUNCTIONS **********************************************************/
31 * The ProtectHandle routine protects an object handle against closure.
33 * @return TRUE or FALSE.
40 ProtectHandle(IN HANDLE ObjectHandle
)
43 OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
;
45 /* Query current state */
46 Status
= NtQueryObject(ObjectHandle
,
47 ObjectHandleFlagInformation
,
51 if (NT_SUCCESS(Status
))
53 /* Enable protect from close */
54 HandleInfo
.ProtectFromClose
= TRUE
;
55 Status
= NtSetInformationObject(ObjectHandle
,
56 ObjectHandleFlagInformation
,
59 if (NT_SUCCESS(Status
)) return TRUE
;
62 /* We failed to or set the state */
67 * @name UnProtectHandle
70 * The UnProtectHandle routine unprotects an object handle against closure.
72 * @return TRUE or FALSE.
79 UnProtectHandle(IN HANDLE ObjectHandle
)
82 OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
;
84 /* Query current state */
85 Status
= NtQueryObject(ObjectHandle
,
86 ObjectHandleFlagInformation
,
90 if (NT_SUCCESS(Status
))
92 /* Disable protect from close */
93 HandleInfo
.ProtectFromClose
= FALSE
;
94 Status
= NtSetInformationObject(ObjectHandle
,
95 ObjectHandleFlagInformation
,
98 if (NT_SUCCESS(Status
)) return TRUE
;
101 /* We failed to or set the state */
106 * @name CsrAllocateThread
108 * The CsrAllocateThread routine allocates a new CSR Thread object.
111 * Pointer to the CSR Process which will contain this CSR Thread.
113 * @return Pointer to the newly allocated CSR Thread.
120 CsrAllocateThread(IN PCSR_PROCESS CsrProcess
)
122 PCSR_THREAD CsrThread
;
124 /* Allocate the structure */
125 CsrThread
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, sizeof(CSR_THREAD
));
126 if (!CsrThread
) return(NULL
);
128 /* Reference the Thread and Process */
129 CsrThread
->ReferenceCount
++;
130 CsrProcess
->ReferenceCount
++;
132 /* Set the Parent Process */
133 CsrThread
->Process
= CsrProcess
;
140 * @name CsrLockedReferenceThread
142 * The CsrLockedReferenceThread references a CSR Thread while the
143 * Process Lock is already being held.
146 * Pointer to the CSR Thread to be referenced.
150 * @remarks This routine will return with the Process Lock held.
155 CsrLockedReferenceThread(IN PCSR_THREAD CsrThread
)
157 /* Increment the reference count */
158 ++CsrThread
->ReferenceCount
;
162 * @name CsrLocateThreadByClientId
164 * The CsrLocateThreadByClientId routine locates the CSR Thread and,
165 * optionally, its parent CSR Process, corresponding to a Client ID.
168 * Optional pointer to a CSR Process pointer which will contain
169 * the CSR Thread's parent.
172 * Pointer to a Client ID structure containing the Unique Thread ID
175 * @return Pointer to the CSR Thread corresponding to this CID, or NULL if
183 CsrLocateThreadByClientId(OUT PCSR_PROCESS
*Process OPTIONAL
,
184 IN PCLIENT_ID ClientId
)
187 PLIST_ENTRY ListHead
, NextEntry
;
188 PCSR_THREAD FoundThread
;
189 // ASSERT(ProcessStructureListLocked());
191 /* Hash the Thread */
192 i
= CsrHashThread(ClientId
->UniqueThread
);
194 /* Set the list pointers */
195 ListHead
= &CsrThreadHashTable
[i
];
196 NextEntry
= ListHead
->Flink
;
199 while (NextEntry
!= ListHead
)
202 FoundThread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, HashLinks
);
204 /* Move to the next entry */
205 NextEntry
= NextEntry
->Flink
;
207 /* Compare the CID */
208 // if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId)
209 if ( FoundThread
->ClientId
.UniqueProcess
== ClientId
->UniqueProcess
&&
210 FoundThread
->ClientId
.UniqueThread
== ClientId
->UniqueThread
)
212 /* Match found, return the process */
213 *Process
= FoundThread
->Process
;
215 /* Return thread too */
216 // DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process);
226 * @name CsrLocateThreadInProcess
228 * The CsrLocateThreadInProcess routine locates the CSR Thread
229 * corresponding to a Client ID inside a specific CSR Process.
232 * Optional pointer to the CSR Process which contains the CSR Thread
233 * that will be looked up.
236 * Pointer to a Client ID structure containing the Unique Thread ID
239 * @return Pointer to the CSR Thread corresponding to this CID, or NULL if
242 * @remarks If the CsrProcess argument is NULL, the lookup will be done inside
248 CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL
,
251 PLIST_ENTRY ListHead
, NextEntry
;
252 PCSR_THREAD FoundThread
= NULL
;
254 /* Use the Root Process if none was specified */
255 if (!CsrProcess
) CsrProcess
= CsrRootProcess
;
257 /* Save the List pointers */
258 // DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount);
259 ListHead
= &CsrProcess
->ThreadList
;
260 NextEntry
= ListHead
->Flink
;
263 while (NextEntry
!= ListHead
)
265 /* Get Thread Entry */
266 FoundThread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, Link
);
268 /* Check for TID Match */
269 if (FoundThread
->ClientId
.UniqueThread
== Cid
->UniqueThread
) break;
271 /* Move to the next entry */
272 NextEntry
= NextEntry
->Flink
;
275 /* Return what we found */
276 // DPRINT1("Found: %p\n", FoundThread);
281 * @name CsrInsertThread
283 * The CsrInsertThread routine inserts a CSR Thread into its parent's
284 * Thread List and into the Thread Hash Table.
287 * Pointer to the CSR Process containing this CSR Thread.
290 * Pointer to the CSR Thread to be inserted.
299 CsrInsertThread(IN PCSR_PROCESS Process
,
300 IN PCSR_THREAD Thread
)
303 // ASSERT(ProcessStructureListLocked());
305 /* Insert it into the Regular List */
306 InsertTailList(&Process
->ThreadList
, &Thread
->Link
);
308 /* Increase Thread Count */
309 Process
->ThreadCount
++;
311 /* Hash the Thread */
312 i
= CsrHashThread(Thread
->ClientId
.UniqueThread
);
313 // DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i);
315 /* Insert it there too */
316 InsertHeadList(&CsrThreadHashTable
[i
], &Thread
->HashLinks
);
320 * @name CsrDeallocateThread
322 * The CsrDeallocateThread frees the memory associated with a CSR Thread.
325 * Pointer to the CSR Thread to be freed.
329 * @remarks Do not call this routine. It is reserved for the internal
330 * thread management routines when a CSR Thread has been cleanly
331 * dereferenced and killed.
336 CsrDeallocateThread(IN PCSR_THREAD CsrThread
)
338 /* Free the process object from the heap */
339 // ASSERT(CsrThread->WaitBlock == NULL);
340 RtlFreeHeap(CsrHeap
, 0, CsrThread
);
344 * @name CsrRemoveThread
346 * The CsrRemoveThread function undoes a CsrInsertThread operation and
347 * removes the CSR Thread from the the Hash Table and Thread List.
350 * Pointer to the CSR Thread to remove.
354 * @remarks If this CSR Thread is the last one inside a CSR Process, the
355 * parent will be dereferenced and the CsrProcessLastThreadTerminated
358 * After executing this routine, the CSR Thread will have the
359 * CsrThreadInTermination flag set.
364 CsrRemoveThread(IN PCSR_THREAD CsrThread
)
366 ASSERT(ProcessStructureListLocked());
368 /* Remove it from the List */
369 RemoveEntryList(&CsrThread
->Link
);
371 /* Decreate the thread count of the process */
372 CsrThread
->Process
->ThreadCount
--;
374 /* Remove it from the Hash List as well */
375 if (CsrThread
->HashLinks
.Flink
) RemoveEntryList(&CsrThread
->HashLinks
);
377 /* Check if this is the last Thread */
378 if (!CsrThread
->Process
->ThreadCount
)
380 /* Check if it's not already been marked for deletion */
381 if (!(CsrThread
->Process
->Flags
& CsrProcessLastThreadTerminated
))
383 /* Let everyone know this process is about to lose the thread */
384 CsrThread
->Process
->Flags
|= CsrProcessLastThreadTerminated
;
386 /* Reference the Process */
387 CsrLockedDereferenceProcess(CsrThread
->Process
);
391 /* Mark the thread for deletion */
392 CsrThread
->Flags
|= CsrThreadInTermination
;
396 * @name CsrThreadRefcountZero
398 * The CsrThreadRefcountZero routine is executed when a CSR Thread has lost
399 * all its active references. It removes and de-allocates the CSR Thread.
402 * Pointer to the CSR Thread that is to be deleted.
406 * @remarks Do not call this routine. It is reserved for the internal
407 * thread management routines when a CSR Thread has lost all
410 * This routine is called with the Process Lock held.
415 CsrThreadRefcountZero(IN PCSR_THREAD CsrThread
)
417 PCSR_PROCESS CsrProcess
= CsrThread
->Process
;
419 ASSERT(ProcessStructureListLocked());
421 /* Remove this thread */
422 CsrRemoveThread(CsrThread
);
424 /* Release the Process Lock */
425 CsrReleaseProcessLock();
427 /* Close the NT Thread Handle */
428 if (CsrThread
->ThreadHandle
)
430 UnProtectHandle(CsrThread
->ThreadHandle
);
431 Status
= NtClose(CsrThread
->ThreadHandle
);
432 ASSERT(NT_SUCCESS(Status
));
435 /* De-allocate the CSR Thread Object */
436 CsrDeallocateThread(CsrThread
);
438 /* Remove a reference from the process */
439 CsrDereferenceProcess(CsrProcess
);
443 * @name CsrLockedDereferenceThread
445 * The CsrLockedDereferenceThread dereferences a CSR Thread while the
446 * Process Lock is already being held.
449 * Pointer to the CSR Thread to be dereferenced.
453 * @remarks This routine will return with the Process Lock held.
458 CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread
)
462 /* Decrease reference count */
463 LockCount
= --CsrThread
->ReferenceCount
;
464 ASSERT(LockCount
>= 0);
467 /* Call the generic cleanup code */
468 CsrThreadRefcountZero(CsrThread
);
469 CsrAcquireProcessLock();
474 /* PUBLIC FUNCTIONS ***********************************************************/
477 * @name CsrAddStaticServerThread
480 * The CsrAddStaticServerThread routine adds a new CSR Thread to the
481 * CSR Server Process (CsrRootProcess).
484 * Handle to an existing NT Thread to which to associate this
488 * Pointer to the Client ID structure of the NT Thread to associate
489 * with this CSR Thread.
492 * Initial CSR Thread Flags to associate to this CSR Thread. Usually
493 * CsrThreadIsServerThread.
495 * @return Pointer to the newly allocated CSR Thread.
502 CsrAddStaticServerThread(IN HANDLE hThread
,
503 IN PCLIENT_ID ClientId
,
504 IN ULONG ThreadFlags
)
506 PCSR_THREAD CsrThread
;
509 CsrAcquireProcessLock();
511 /* Allocate the Server Thread */
512 CsrThread
= CsrAllocateThread(CsrRootProcess
);
515 /* Setup the Object */
516 CsrThread
->ThreadHandle
= hThread
;
517 ProtectHandle(hThread
);
518 CsrThread
->ClientId
= *ClientId
;
519 CsrThread
->Flags
= ThreadFlags
;
521 /* Insert it into the Thread List */
522 InsertTailList(&CsrRootProcess
->ThreadList
, &CsrThread
->Link
);
524 /* Increment the thread count */
525 CsrRootProcess
->ThreadCount
++;
529 DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread
);
532 /* Release the Process Lock and return */
533 CsrReleaseProcessLock();
538 * @name CsrCreateRemoteThread
541 * The CsrCreateRemoteThread routine creates a CSR Thread object for
542 * an NT Thread which is not part of the current NT Process.
545 * Handle to an existing NT Thread to which to associate this
549 * Pointer to the Client ID structure of the NT Thread to associate
550 * with this CSR Thread.
552 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
560 CsrCreateRemoteThread(IN HANDLE hThread
,
561 IN PCLIENT_ID ClientId
)
565 PCSR_THREAD CsrThread
;
566 PCSR_PROCESS CsrProcess
;
567 KERNEL_USER_TIMES KernelTimes
;
568 DPRINT("CSRSRV: %s called\n", __FUNCTION__
);
570 /* Get the Thread Create Time */
571 Status
= NtQueryInformationThread(hThread
,
576 if (!NT_SUCCESS(Status
))
578 DPRINT1("Failed to query thread times: %lx\n", Status
);
582 /* Lock the Owner Process */
583 Status
= CsrLockProcessByClientId(ClientId
->UniqueProcess
, &CsrProcess
);
584 if (!NT_SUCCESS(Status
))
586 DPRINT1("No known process for %lx\n", ClientId
->UniqueProcess
);
590 /* Make sure the thread didn't terminate */
591 if (KernelTimes
.ExitTime
.QuadPart
)
593 /* Unlock the process and return */
594 CsrUnlockProcess(CsrProcess
);
595 DPRINT1("Dead thread: %I64x\n", KernelTimes
.ExitTime
.QuadPart
);
596 return STATUS_THREAD_IS_TERMINATING
;
599 /* Allocate a CSR Thread Structure */
600 CsrThread
= CsrAllocateThread(CsrProcess
);
603 DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__
);
604 CsrUnlockProcess(CsrProcess
);
605 return STATUS_NO_MEMORY
;
608 /* Duplicate the Thread Handle */
609 Status
= NtDuplicateObject(NtCurrentProcess(),
615 DUPLICATE_SAME_ACCESS
);
617 if (!NT_SUCCESS(Status
))
619 DPRINT1("Thread duplication failed: %lx\n", Status
);
620 ThreadHandle
= hThread
;
623 /* Save the data we have */
624 CsrThread
->CreateTime
= KernelTimes
.CreateTime
;
625 CsrThread
->ClientId
= *ClientId
;
626 CsrThread
->ThreadHandle
= ThreadHandle
;
627 ProtectHandle(ThreadHandle
);
628 CsrThread
->Flags
= 0;
630 /* Insert the Thread into the Process */
631 CsrInsertThread(CsrProcess
, CsrThread
);
633 /* Release the lock and return */
634 CsrUnlockProcess(CsrProcess
);
635 return STATUS_SUCCESS
;
639 * @name CsrCreateThread
642 * The CsrCreateThread routine creates a CSR Thread object for an NT Thread.
645 * Pointer to the CSR Process which will contain the CSR Thread.
648 * Handle to an existing NT Thread to which to associate this
652 * Pointer to the Client ID structure of the NT Thread to associate
653 * with this CSR Thread.
655 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
663 CsrCreateThread(IN PCSR_PROCESS CsrProcess
,
665 IN PCLIENT_ID ClientId
,
666 IN BOOLEAN HaveClient
)
669 PCSR_THREAD CsrThread
, CurrentThread
;
670 PCSR_PROCESS CurrentProcess
;
671 CLIENT_ID CurrentCid
;
672 KERNEL_USER_TIMES KernelTimes
;
674 DPRINT("CSRSRV: %s called\n", __FUNCTION__
);
678 /* Get the current thread and CID */
679 CurrentThread
= CsrGetClientThread();
680 CurrentCid
= CurrentThread
->ClientId
;
682 /* Acquire the Process Lock */
683 CsrAcquireProcessLock();
685 /* Get the current Process and make sure the Thread is valid with this CID */
686 CurrentThread
= CsrLocateThreadByClientId(&CurrentProcess
, &CurrentCid
);
688 /* Something is wrong if we get an empty thread back */
691 DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__
);
692 CsrReleaseProcessLock();
693 return STATUS_THREAD_IS_TERMINATING
;
698 /* Acquire the Process Lock */
699 CsrAcquireProcessLock();
702 /* Get the Thread Create Time */
703 Status
= NtQueryInformationThread(hThread
,
708 if (!NT_SUCCESS(Status
))
710 CsrReleaseProcessLock();
714 /* Allocate a CSR Thread Structure */
715 CsrThread
= CsrAllocateThread(CsrProcess
);
718 DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__
);
719 CsrReleaseProcessLock();
720 return STATUS_NO_MEMORY
;
723 /* Save the data we have */
724 CsrThread
->CreateTime
= KernelTimes
.CreateTime
;
725 CsrThread
->ClientId
= *ClientId
;
726 CsrThread
->ThreadHandle
= hThread
;
727 ProtectHandle(hThread
);
728 CsrThread
->Flags
= 0;
730 /* Insert the Thread into the Process */
731 CsrInsertThread(CsrProcess
, CsrThread
);
733 /* Release the lock and return */
734 CsrReleaseProcessLock();
736 return STATUS_SUCCESS
;
740 * @name CsrDereferenceThread
743 * The CsrDereferenceThread routine removes a reference from a CSR Thread.
746 * Pointer to the CSR Thread to dereference.
750 * @remarks If the reference count has reached zero (ie: the CSR Thread has
751 * no more active references), it will be deleted.
756 CsrDereferenceThread(IN PCSR_THREAD CsrThread
)
758 /* Acquire process lock */
759 CsrAcquireProcessLock();
761 /* Decrease reference count */
762 ASSERT(CsrThread
->ReferenceCount
> 0);
763 if (!(--CsrThread
->ReferenceCount
))
765 /* Call the generic cleanup code */
766 CsrThreadRefcountZero(CsrThread
);
770 /* Just release the lock */
771 CsrReleaseProcessLock();
776 * @name CsrDestroyThread
779 * The CsrDestroyThread routine destroys the CSR Thread corresponding to
783 * Pointer to the Client ID Structure corresponding to the CSR
784 * Thread which is about to be destroyed.
786 * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
787 * if the CSR Thread is already terminating.
794 CsrDestroyThread(IN PCLIENT_ID Cid
)
796 CLIENT_ID ClientId
= *Cid
;
797 PCSR_THREAD CsrThread
;
798 PCSR_PROCESS CsrProcess
;
801 CsrAcquireProcessLock();
803 /* Find the thread */
804 CsrThread
= CsrLocateThreadByClientId(&CsrProcess
,
807 /* Make sure we got one back, and that it's not already gone */
808 if (!CsrThread
|| CsrThread
->Flags
& CsrThreadTerminated
)
810 /* Release the lock and return failure */
811 CsrReleaseProcessLock();
812 return STATUS_THREAD_IS_TERMINATING
;
815 /* Set the terminated flag */
816 CsrThread
->Flags
|= CsrThreadTerminated
;
818 /* Acquire the Wait Lock */
819 CsrAcquireWaitLock();
821 /* Do we have an active wait block? */
822 if (CsrThread
->WaitBlock
)
824 /* Notify waiters of termination */
825 CsrNotifyWaitBlock(CsrThread
->WaitBlock
,
829 CsrProcessTerminating
,
833 /* Release the Wait Lock */
834 CsrReleaseWaitLock();
836 /* Dereference the thread */
837 CsrLockedDereferenceThread(CsrThread
);
839 /* Release the Process Lock and return success */
840 CsrReleaseProcessLock();
841 return STATUS_SUCCESS
;
845 * @name CsrExecServerThread
848 * The CsrExecServerThread routine creates an NT Thread and then
849 * initializes a CSR Thread for it.
851 * @param ThreadHandler
852 * Pointer to the thread's startup routine.
855 * Initial CSR Thread Flags to set to the CSR Thread.
857 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
860 * @remarks This routine is similar to CsrAddStaticServerThread, but it
861 * also creates an NT Thread instead of expecting one to already
867 CsrExecServerThread(IN PVOID ThreadHandler
,
870 PCSR_THREAD CsrThread
;
875 /* Acquire process lock */
876 CsrAcquireProcessLock();
878 /* Allocate a CSR Thread in the Root Process */
879 ASSERT(CsrRootProcess
!= NULL
);
880 CsrThread
= CsrAllocateThread(CsrRootProcess
);
884 CsrReleaseProcessLock();
885 return STATUS_NO_MEMORY
;
888 /* Create the Thread */
889 Status
= RtlCreateUserThread(NtCurrentProcess(),
899 if (!NT_SUCCESS(Status
))
902 CsrDeallocateThread(CsrThread
);
903 CsrReleaseProcessLock();
907 /* Setup the Thread Object */
908 CsrThread
->ThreadHandle
= hThread
;
909 ProtectHandle(hThread
);
910 CsrThread
->ClientId
= ClientId
;
911 CsrThread
->Flags
= Flags
;
913 /* Insert it into the Thread List */
914 InsertHeadList(&CsrRootProcess
->ThreadList
, &CsrThread
->Link
);
916 /* Increase the thread count */
917 CsrRootProcess
->ThreadCount
++;
920 CsrReleaseProcessLock();
925 * @name CsrLockThreadByClientId
928 * The CsrLockThreadByClientId routine locks the CSR Thread corresponding
929 * to the given Thread ID and optionally returns it.
932 * Thread ID corresponding to the CSR Thread which will be locked.
935 * Optional pointer to a CSR Thread pointer which will hold the
936 * CSR Thread corresponding to the given Thread ID.
938 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
941 * @remarks Locking a CSR Thread is defined as acquiring an extra
942 * reference to it and returning with the Process Lock held.
947 CsrLockThreadByClientId(IN HANDLE Tid
,
948 OUT PCSR_THREAD
*CsrThread
)
950 PLIST_ENTRY NextEntry
;
951 PCSR_THREAD CurrentThread
= NULL
;
952 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
955 /* Acquire the lock */
956 CsrAcquireProcessLock();
959 ASSERT(CsrThread
!= NULL
);
962 /* Convert to Hash */
963 i
= CsrHashThread(Tid
);
965 /* Setup the List Pointers */
966 NextEntry
= CsrThreadHashTable
[i
].Flink
;
969 while (NextEntry
!= &CsrThreadHashTable
[i
])
971 /* Get the Process */
972 CurrentThread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, HashLinks
);
974 /* Check for PID Match */
975 if ((CurrentThread
->ClientId
.UniqueThread
== Tid
) &&
976 !(CurrentThread
->Flags
& CsrThreadTerminated
))
978 /* Get out of here */
982 /* Move to the next entry */
983 NextEntry
= NextEntry
->Flink
;
986 /* Nothing found if we got back to the list */
987 if (NextEntry
== &CsrThreadHashTable
[i
]) CurrentThread
= NULL
;
989 /* Did the loop find something? */
992 /* Reference the found thread */
993 Status
= STATUS_SUCCESS
;
994 CurrentThread
->ReferenceCount
++;
995 *CsrThread
= CurrentThread
;
999 /* Nothing found, release the lock */
1000 Status
= STATUS_UNSUCCESSFUL
;
1001 CsrReleaseProcessLock();
1004 /* Return the status */
1009 * @name CsrReferenceThread
1012 * The CsrReferenceThread routine increases the active reference count of
1016 * Pointer to the CSR Thread whose reference count will be increased.
1020 * @remarks Do not use this routine if the Process Lock is already held.
1025 CsrReferenceThread(IN PCSR_THREAD CsrThread
)
1027 /* Acquire process lock */
1028 CsrAcquireProcessLock();
1031 ASSERT(CsrThread
->Flags
& CsrThreadTerminated
); // CSR_THREAD_DESTROYED in ASSERT
1032 ASSERT(CsrThread
->ReferenceCount
!= 0);
1034 /* Increment reference count */
1035 CsrThread
->ReferenceCount
++;
1037 /* Release the lock */
1038 CsrReleaseProcessLock();
1042 * @name CsrUnlockThread
1045 * The CsrUnlockThread undoes a previous CsrLockThreadByClientId operation.
1048 * Pointer to a previously locked CSR Thread.
1050 * @return STATUS_SUCCESS.
1052 * @remarks This routine must be called with the Process Lock held.
1057 CsrUnlockThread(IN PCSR_THREAD CsrThread
)
1059 /* Dereference the Thread */
1060 ASSERT(ProcessStructureListLocked());
1061 CsrLockedDereferenceThread(CsrThread
);
1063 /* Release the lock and return */
1064 CsrReleaseProcessLock();
1065 return STATUS_SUCCESS
;