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 CsrLockedReferenceThread(CsrThread
);
130 CsrLockedReferenceProcess(CsrProcess
);
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 if (Process
) *Process
= NULL
;
193 /* Hash the Thread */
194 i
= CsrHashThread(ClientId
->UniqueThread
);
196 /* Set the list pointers */
197 ListHead
= &CsrThreadHashTable
[i
];
198 NextEntry
= ListHead
->Flink
;
201 while (NextEntry
!= ListHead
)
204 FoundThread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, HashLinks
);
206 /* Move to the next entry */
207 NextEntry
= NextEntry
->Flink
;
209 /* Compare the CID */
210 // if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId)
211 if ( FoundThread
->ClientId
.UniqueProcess
== ClientId
->UniqueProcess
&&
212 FoundThread
->ClientId
.UniqueThread
== ClientId
->UniqueThread
)
214 /* Match found, return the process */
215 if (Process
) *Process
= FoundThread
->Process
;
217 /* Return thread too */
218 // DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process);
228 * @name CsrLocateThreadInProcess
230 * The CsrLocateThreadInProcess routine locates the CSR Thread
231 * corresponding to a Client ID inside a specific CSR Process.
234 * Optional pointer to the CSR Process which contains the CSR Thread
235 * that will be looked up.
238 * Pointer to a Client ID structure containing the Unique Thread ID
241 * @return Pointer to the CSR Thread corresponding to this CID, or NULL if
244 * @remarks If the CsrProcess argument is NULL, the lookup will be done inside
250 CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL
,
253 PLIST_ENTRY ListHead
, NextEntry
;
254 PCSR_THREAD FoundThread
= NULL
;
256 /* Use the Root Process if none was specified */
257 if (!CsrProcess
) CsrProcess
= CsrRootProcess
;
259 /* Save the List pointers */
260 // DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount);
261 ListHead
= &CsrProcess
->ThreadList
;
262 NextEntry
= ListHead
->Flink
;
265 while (NextEntry
!= ListHead
)
267 /* Get Thread Entry */
268 FoundThread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, Link
);
270 /* Check for TID Match */
271 if (FoundThread
->ClientId
.UniqueThread
== Cid
->UniqueThread
) break;
273 /* Move to the next entry */
274 NextEntry
= NextEntry
->Flink
;
277 /* Return what we found */
278 // DPRINT1("Found: %p\n", FoundThread);
283 * @name CsrInsertThread
285 * The CsrInsertThread routine inserts a CSR Thread into its parent's
286 * Thread List and into the Thread Hash Table.
289 * Pointer to the CSR Process containing this CSR Thread.
292 * Pointer to the CSR Thread to be inserted.
301 CsrInsertThread(IN PCSR_PROCESS Process
,
302 IN PCSR_THREAD Thread
)
305 // ASSERT(ProcessStructureListLocked());
307 /* Insert it into the Regular List */
308 InsertTailList(&Process
->ThreadList
, &Thread
->Link
);
310 /* Increase Thread Count */
311 Process
->ThreadCount
++;
313 /* Hash the Thread */
314 i
= CsrHashThread(Thread
->ClientId
.UniqueThread
);
315 // DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i);
317 /* Insert it there too */
318 InsertHeadList(&CsrThreadHashTable
[i
], &Thread
->HashLinks
);
322 * @name CsrDeallocateThread
324 * The CsrDeallocateThread frees the memory associated with a CSR Thread.
327 * Pointer to the CSR Thread to be freed.
331 * @remarks Do not call this routine. It is reserved for the internal
332 * thread management routines when a CSR Thread has been cleanly
333 * dereferenced and killed.
338 CsrDeallocateThread(IN PCSR_THREAD CsrThread
)
340 /* Free the process object from the heap */
341 // ASSERT(CsrThread->WaitBlock == NULL);
342 RtlFreeHeap(CsrHeap
, 0, CsrThread
);
346 * @name CsrRemoveThread
348 * The CsrRemoveThread function undoes a CsrInsertThread operation and
349 * removes the CSR Thread from the the Hash Table and Thread List.
352 * Pointer to the CSR Thread to remove.
356 * @remarks If this CSR Thread is the last one inside a CSR Process, the
357 * parent will be dereferenced and the CsrProcessLastThreadTerminated
360 * After executing this routine, the CSR Thread will have the
361 * CsrThreadInTermination flag set.
366 CsrRemoveThread(IN PCSR_THREAD CsrThread
)
368 ASSERT(ProcessStructureListLocked());
370 /* Remove it from the List */
371 RemoveEntryList(&CsrThread
->Link
);
373 /* Decreate the thread count of the process */
374 CsrThread
->Process
->ThreadCount
--;
376 /* Remove it from the Hash List as well */
377 if (CsrThread
->HashLinks
.Flink
) RemoveEntryList(&CsrThread
->HashLinks
);
379 /* Check if this is the last Thread */
380 if (!CsrThread
->Process
->ThreadCount
)
382 /* Check if it's not already been marked for deletion */
383 if (!(CsrThread
->Process
->Flags
& CsrProcessLastThreadTerminated
))
385 /* Let everyone know this process is about to lose the thread */
386 CsrThread
->Process
->Flags
|= CsrProcessLastThreadTerminated
;
388 /* Reference the Process */
389 CsrLockedDereferenceProcess(CsrThread
->Process
);
393 /* Mark the thread for deletion */
394 CsrThread
->Flags
|= CsrThreadInTermination
;
398 * @name CsrThreadRefcountZero
400 * The CsrThreadRefcountZero routine is executed when a CSR Thread has lost
401 * all its active references. It removes and de-allocates the CSR Thread.
404 * Pointer to the CSR Thread that is to be deleted.
408 * @remarks Do not call this routine. It is reserved for the internal
409 * thread management routines when a CSR Thread has lost all
412 * This routine is called with the Process Lock held.
417 CsrThreadRefcountZero(IN PCSR_THREAD CsrThread
)
419 PCSR_PROCESS CsrProcess
= CsrThread
->Process
;
421 ASSERT(ProcessStructureListLocked());
423 /* Remove this thread */
424 CsrRemoveThread(CsrThread
);
426 /* Release the Process Lock */
427 CsrReleaseProcessLock();
429 /* Close the NT Thread Handle */
430 if (CsrThread
->ThreadHandle
)
432 UnProtectHandle(CsrThread
->ThreadHandle
);
433 Status
= NtClose(CsrThread
->ThreadHandle
);
434 ASSERT(NT_SUCCESS(Status
));
437 /* De-allocate the CSR Thread Object */
438 CsrDeallocateThread(CsrThread
);
440 /* Remove a reference from the process */
441 CsrDereferenceProcess(CsrProcess
);
445 * @name CsrLockedDereferenceThread
447 * The CsrLockedDereferenceThread dereferences a CSR Thread while the
448 * Process Lock is already being held.
451 * Pointer to the CSR Thread to be dereferenced.
455 * @remarks This routine will return with the Process Lock held.
460 CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread
)
464 /* Decrease reference count */
465 LockCount
= --CsrThread
->ReferenceCount
;
466 ASSERT(LockCount
>= 0);
469 /* Call the generic cleanup code */
470 CsrAcquireProcessLock();
471 CsrThreadRefcountZero(CsrThread
);
476 /* PUBLIC FUNCTIONS ***********************************************************/
479 * @name CsrAddStaticServerThread
482 * The CsrAddStaticServerThread routine adds a new CSR Thread to the
483 * CSR Server Process (CsrRootProcess).
486 * Handle to an existing NT Thread to which to associate this
490 * Pointer to the Client ID structure of the NT Thread to associate
491 * with this CSR Thread.
494 * Initial CSR Thread Flags to associate to this CSR Thread. Usually
495 * CsrThreadIsServerThread.
497 * @return Pointer to the newly allocated CSR Thread.
504 CsrAddStaticServerThread(IN HANDLE hThread
,
505 IN PCLIENT_ID ClientId
,
506 IN ULONG ThreadFlags
)
508 PCSR_THREAD CsrThread
;
511 CsrAcquireProcessLock();
513 /* Allocate the Server Thread */
514 CsrThread
= CsrAllocateThread(CsrRootProcess
);
517 /* Setup the Object */
518 CsrThread
->ThreadHandle
= hThread
;
519 ProtectHandle(hThread
);
520 CsrThread
->ClientId
= *ClientId
;
521 CsrThread
->Flags
= ThreadFlags
;
523 /* Insert it into the Thread List */
524 InsertTailList(&CsrRootProcess
->ThreadList
, &CsrThread
->Link
);
526 /* Increment the thread count */
527 CsrRootProcess
->ThreadCount
++;
531 DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread
);
534 /* Release the Process Lock and return */
535 CsrReleaseProcessLock();
540 * @name CsrCreateRemoteThread
543 * The CsrCreateRemoteThread routine creates a CSR Thread object for
544 * an NT Thread which is not part of the current NT Process.
547 * Handle to an existing NT Thread to which to associate this
551 * Pointer to the Client ID structure of the NT Thread to associate
552 * with this CSR Thread.
554 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
562 CsrCreateRemoteThread(IN HANDLE hThread
,
563 IN PCLIENT_ID ClientId
)
567 PCSR_THREAD CsrThread
;
568 PCSR_PROCESS CsrProcess
;
569 KERNEL_USER_TIMES KernelTimes
;
570 DPRINT("CSRSRV: %s called\n", __FUNCTION__
);
572 /* Get the Thread Create Time */
573 Status
= NtQueryInformationThread(hThread
,
578 if (!NT_SUCCESS(Status
))
580 DPRINT1("Failed to query thread times: %lx\n", Status
);
584 /* Lock the Owner Process */
585 Status
= CsrLockProcessByClientId(ClientId
->UniqueProcess
, &CsrProcess
);
586 if (!NT_SUCCESS(Status
))
588 DPRINT1("No known process for %lx\n", ClientId
->UniqueProcess
);
592 /* Make sure the thread didn't terminate */
593 if (KernelTimes
.ExitTime
.QuadPart
)
595 /* Unlock the process and return */
596 CsrUnlockProcess(CsrProcess
);
597 DPRINT1("Dead thread: %I64x\n", KernelTimes
.ExitTime
.QuadPart
);
598 return STATUS_THREAD_IS_TERMINATING
;
601 /* Allocate a CSR Thread Structure */
602 CsrThread
= CsrAllocateThread(CsrProcess
);
605 DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__
);
606 CsrUnlockProcess(CsrProcess
);
607 return STATUS_NO_MEMORY
;
610 /* Duplicate the Thread Handle */
611 Status
= NtDuplicateObject(NtCurrentProcess(),
617 DUPLICATE_SAME_ACCESS
);
619 if (!NT_SUCCESS(Status
))
621 DPRINT1("Thread duplication failed: %lx\n", Status
);
622 ThreadHandle
= hThread
;
625 /* Save the data we have */
626 CsrThread
->CreateTime
= KernelTimes
.CreateTime
;
627 CsrThread
->ClientId
= *ClientId
;
628 CsrThread
->ThreadHandle
= ThreadHandle
;
629 ProtectHandle(ThreadHandle
);
630 CsrThread
->Flags
= 0;
632 /* Insert the Thread into the Process */
633 CsrInsertThread(CsrProcess
, CsrThread
);
635 /* Release the lock and return */
636 CsrUnlockProcess(CsrProcess
);
637 return STATUS_SUCCESS
;
641 * @name CsrCreateThread
644 * The CsrCreateThread routine creates a CSR Thread object for an NT Thread.
647 * Pointer to the CSR Process which will contain the CSR Thread.
650 * Handle to an existing NT Thread to which to associate this
654 * Pointer to the Client ID structure of the NT Thread to associate
655 * with this CSR Thread.
657 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
665 CsrCreateThread(IN PCSR_PROCESS CsrProcess
,
667 IN PCLIENT_ID ClientId
,
668 IN BOOLEAN HaveClient
)
671 PCSR_THREAD CsrThread
, CurrentThread
;
672 PCSR_PROCESS CurrentProcess
;
673 CLIENT_ID CurrentCid
;
674 KERNEL_USER_TIMES KernelTimes
;
676 DPRINT("CSRSRV: %s called\n", __FUNCTION__
);
680 /* Get the current thread and CID */
681 CurrentThread
= CsrGetClientThread();
682 CurrentCid
= CurrentThread
->ClientId
;
684 /* Acquire the Process Lock */
685 CsrAcquireProcessLock();
687 /* Get the current Process and make sure the Thread is valid with this CID */
688 CurrentThread
= CsrLocateThreadByClientId(&CurrentProcess
, &CurrentCid
);
690 /* Something is wrong if we get an empty thread back */
693 DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__
);
694 CsrReleaseProcessLock();
695 return STATUS_THREAD_IS_TERMINATING
;
700 /* Acquire the Process Lock */
701 CsrAcquireProcessLock();
704 /* Get the Thread Create Time */
705 Status
= NtQueryInformationThread(hThread
,
710 if (!NT_SUCCESS(Status
))
712 CsrReleaseProcessLock();
716 /* Allocate a CSR Thread Structure */
717 CsrThread
= CsrAllocateThread(CsrProcess
);
720 DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__
);
721 CsrReleaseProcessLock();
722 return STATUS_NO_MEMORY
;
725 /* Save the data we have */
726 CsrThread
->CreateTime
= KernelTimes
.CreateTime
;
727 CsrThread
->ClientId
= *ClientId
;
728 CsrThread
->ThreadHandle
= hThread
;
729 ProtectHandle(hThread
);
730 CsrThread
->Flags
= 0;
732 /* Insert the Thread into the Process */
733 CsrInsertThread(CsrProcess
, CsrThread
);
735 /* Release the lock and return */
736 CsrReleaseProcessLock();
738 return STATUS_SUCCESS
;
742 * @name CsrDereferenceThread
745 * The CsrDereferenceThread routine removes a reference from a CSR Thread.
748 * Pointer to the CSR Thread to dereference.
752 * @remarks If the reference count has reached zero (ie: the CSR Thread has
753 * no more active references), it will be deleted.
758 CsrDereferenceThread(IN PCSR_THREAD CsrThread
)
760 /* Acquire process lock */
761 CsrAcquireProcessLock();
763 /* Decrease reference count */
764 ASSERT(CsrThread
->ReferenceCount
> 0);
765 if (!(--CsrThread
->ReferenceCount
))
767 /* Call the generic cleanup code */
768 CsrThreadRefcountZero(CsrThread
);
772 /* Just release the lock */
773 CsrReleaseProcessLock();
778 * @name CsrDestroyThread
781 * The CsrDestroyThread routine destroys the CSR Thread corresponding to
785 * Pointer to the Client ID Structure corresponding to the CSR
786 * Thread which is about to be destroyed.
788 * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
789 * if the CSR Thread is already terminating.
796 CsrDestroyThread(IN PCLIENT_ID Cid
)
798 CLIENT_ID ClientId
= *Cid
;
799 PCSR_THREAD CsrThread
;
800 PCSR_PROCESS CsrProcess
;
803 CsrAcquireProcessLock();
805 /* Find the thread */
806 CsrThread
= CsrLocateThreadByClientId(&CsrProcess
,
809 /* Make sure we got one back, and that it's not already gone */
810 if (!CsrThread
|| CsrThread
->Flags
& CsrThreadTerminated
)
812 /* Release the lock and return failure */
813 CsrReleaseProcessLock();
814 return STATUS_THREAD_IS_TERMINATING
;
817 /* Set the terminated flag */
818 CsrThread
->Flags
|= CsrThreadTerminated
;
820 /* Acquire the Wait Lock */
821 CsrAcquireWaitLock();
823 /* Do we have an active wait block? */
824 if (CsrThread
->WaitBlock
)
826 /* Notify waiters of termination */
827 CsrNotifyWaitBlock(CsrThread
->WaitBlock
,
831 CsrProcessTerminating
,
835 /* Release the Wait Lock */
836 CsrReleaseWaitLock();
838 /* Dereference the thread */
839 CsrLockedDereferenceThread(CsrThread
);
841 /* Release the Process Lock and return success */
842 CsrReleaseProcessLock();
843 return STATUS_SUCCESS
;
847 * @name CsrExecServerThread
850 * The CsrExecServerThread routine creates an NT Thread and then
851 * initializes a CSR Thread for it.
853 * @param ThreadHandler
854 * Pointer to the thread's startup routine.
857 * Initial CSR Thread Flags to set to the CSR Thread.
859 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
862 * @remarks This routine is similar to CsrAddStaticServerThread, but it
863 * also creates an NT Thread instead of expecting one to already
869 CsrExecServerThread(IN PVOID ThreadHandler
,
872 PCSR_THREAD CsrThread
;
877 /* Acquire process lock */
878 CsrAcquireProcessLock();
880 /* Allocate a CSR Thread in the Root Process */
881 ASSERT(CsrRootProcess
!= NULL
);
882 CsrThread
= CsrAllocateThread(CsrRootProcess
);
886 CsrReleaseProcessLock();
887 return STATUS_NO_MEMORY
;
890 /* Create the Thread */
891 Status
= RtlCreateUserThread(NtCurrentProcess(),
901 if (!NT_SUCCESS(Status
))
904 CsrDeallocateThread(CsrThread
);
905 CsrReleaseProcessLock();
909 /* Setup the Thread Object */
910 CsrThread
->ThreadHandle
= hThread
;
911 ProtectHandle(hThread
);
912 CsrThread
->ClientId
= ClientId
;
913 CsrThread
->Flags
= Flags
;
915 /* Insert it into the Thread List */
916 InsertHeadList(&CsrRootProcess
->ThreadList
, &CsrThread
->Link
);
918 /* Increase the thread count */
919 CsrRootProcess
->ThreadCount
++;
922 CsrReleaseProcessLock();
927 * @name CsrLockThreadByClientId
930 * The CsrLockThreadByClientId routine locks the CSR Thread corresponding
931 * to the given Thread ID and optionally returns it.
934 * Thread ID corresponding to the CSR Thread which will be locked.
937 * Optional pointer to a CSR Thread pointer which will hold the
938 * CSR Thread corresponding to the given Thread ID.
940 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
943 * @remarks Locking a CSR Thread is defined as acquiring an extra
944 * reference to it and returning with the Process Lock held.
949 CsrLockThreadByClientId(IN HANDLE Tid
,
950 OUT PCSR_THREAD
*CsrThread
)
952 PLIST_ENTRY NextEntry
;
953 PCSR_THREAD CurrentThread
= NULL
;
954 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
957 /* Acquire the lock */
958 CsrAcquireProcessLock();
961 ASSERT(CsrThread
!= NULL
);
964 /* Convert to Hash */
965 i
= CsrHashThread(Tid
);
967 /* Setup the List Pointers */
968 NextEntry
= CsrThreadHashTable
[i
].Flink
;
971 while (NextEntry
!= &CsrThreadHashTable
[i
])
973 /* Get the Process */
974 CurrentThread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, HashLinks
);
976 /* Check for PID Match */
977 if ((CurrentThread
->ClientId
.UniqueThread
== Tid
) &&
978 !(CurrentThread
->Flags
& CsrThreadTerminated
))
980 /* Get out of here */
984 /* Move to the next entry */
985 NextEntry
= NextEntry
->Flink
;
988 /* Nothing found if we got back to the list */
989 if (NextEntry
== &CsrThreadHashTable
[i
]) CurrentThread
= NULL
;
991 /* Did the loop find something? */
994 /* Reference the found thread */
995 Status
= STATUS_SUCCESS
;
996 CsrLockedReferenceThread(CurrentThread
);
997 *CsrThread
= CurrentThread
;
1001 /* Nothing found, release the lock */
1002 Status
= STATUS_UNSUCCESSFUL
;
1003 CsrReleaseProcessLock();
1006 /* Return the status */
1011 * @name CsrReferenceThread
1014 * The CsrReferenceThread routine increases the active reference count of
1018 * Pointer to the CSR Thread whose reference count will be increased.
1022 * @remarks Do not use this routine if the Process Lock is already held.
1027 CsrReferenceThread(IN PCSR_THREAD CsrThread
)
1029 /* Acquire process lock */
1030 CsrAcquireProcessLock();
1033 ASSERT(CsrThread
->Flags
& CsrThreadTerminated
); // CSR_THREAD_DESTROYED in ASSERT
1034 ASSERT(CsrThread
->ReferenceCount
!= 0);
1036 /* Increment reference count */
1037 CsrThread
->ReferenceCount
++;
1039 /* Release the lock */
1040 CsrReleaseProcessLock();
1044 * @name CsrUnlockThread
1047 * The CsrUnlockThread undoes a previous CsrLockThreadByClientId operation.
1050 * Pointer to a previously locked CSR Thread.
1052 * @return STATUS_SUCCESS.
1054 * @remarks This routine must be called with the Process Lock held.
1059 CsrUnlockThread(IN PCSR_THREAD CsrThread
)
1061 /* Dereference the Thread */
1062 ASSERT(ProcessStructureListLocked());
1063 CsrLockedDereferenceThread(CsrThread
);
1065 /* Release the lock and return */
1066 CsrReleaseProcessLock();
1067 return STATUS_SUCCESS
;