3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/suspend.c
6 * PURPOSE: Thread managment
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES ******************************************************************/
15 #include <internal/debug.h>
17 /* NOTES **********************************************************************
21 /* GLOBALS *******************************************************************/
23 static FAST_MUTEX SuspendMutex
;
25 /* FUNCTIONS *****************************************************************/
28 PiSuspendThreadRundownRoutine(PKAPC Apc
)
34 PiSuspendThreadKernelRoutine(PKAPC Apc
,
35 PKNORMAL_ROUTINE
* NormalRoutine
,
37 PVOID
* SystemArgument1
,
38 PVOID
* SystemArguemnt2
)
44 PiSuspendThreadNormalRoutine(PVOID NormalContext
,
45 PVOID SystemArgument1
,
46 PVOID SystemArgument2
)
48 PETHREAD CurrentThread
= PsGetCurrentThread();
49 while (CurrentThread
->Tcb
.SuspendCount
> 0)
51 KeWaitForSingleObject(&CurrentThread
->Tcb
.SuspendSemaphore
,
61 PsResumeThread (PETHREAD Thread
,
64 DPRINT("PsResumeThread (Thread %p SuspendCount %p) called\n");
66 ExAcquireFastMutex (&SuspendMutex
);
68 if (SuspendCount
!= NULL
)
70 *SuspendCount
= Thread
->Tcb
.SuspendCount
;
73 if (Thread
->Tcb
.SuspendCount
> 0)
75 Thread
->Tcb
.SuspendCount
--;
76 if (Thread
->Tcb
.SuspendCount
== 0)
78 KeReleaseSemaphore (&Thread
->Tcb
.SuspendSemaphore
,
85 ExReleaseFastMutex (&SuspendMutex
);
87 return STATUS_SUCCESS
;
92 PsSuspendThread(PETHREAD Thread
, PULONG PreviousSuspendCount
)
96 ExAcquireFastMutex(&SuspendMutex
);
97 OldValue
= Thread
->Tcb
.SuspendCount
;
98 Thread
->Tcb
.SuspendCount
++;
99 if (!Thread
->Tcb
.SuspendApc
.Inserted
)
101 if (!KeInsertQueueApc(&Thread
->Tcb
.SuspendApc
,
106 Thread
->Tcb
.SuspendCount
--;
107 ExReleaseFastMutex(&SuspendMutex
);
108 return(STATUS_THREAD_IS_TERMINATING
);
111 ExReleaseFastMutex(&SuspendMutex
);
112 if (PreviousSuspendCount
!= NULL
)
114 *PreviousSuspendCount
= OldValue
;
116 return(STATUS_SUCCESS
);
121 NtResumeThread(IN HANDLE ThreadHandle
,
122 IN PULONG SuspendCount OPTIONAL
)
124 * FUNCTION: Decrements a thread's resume count
126 * ThreadHandle = Handle to the thread that should be resumed
127 * ResumeCount = The resulting resume count.
137 DPRINT("NtResumeThead(ThreadHandle %lx SuspendCount %p)\n",
138 ThreadHandle
, SuspendCount
);
140 Status
= ObReferenceObjectByHandle (ThreadHandle
,
141 THREAD_SUSPEND_RESUME
,
146 if (!NT_SUCCESS(Status
))
151 Status
= PsResumeThread (Thread
, &Count
);
152 if (!NT_SUCCESS(Status
))
154 ObDereferenceObject ((PVOID
)Thread
);
158 if (SuspendCount
!= NULL
)
160 *SuspendCount
= Count
;
163 ObDereferenceObject ((PVOID
)Thread
);
165 return STATUS_SUCCESS
;
170 NtSuspendThread(IN HANDLE ThreadHandle
,
171 IN PULONG PreviousSuspendCount OPTIONAL
)
173 * FUNCTION: Increments a thread's suspend count
175 * ThreadHandle = Handle to the thread that should be resumed
176 * PreviousSuspendCount = The resulting/previous suspend count.
178 * A thread will be suspended if its suspend count is greater than 0.
179 * This procedure maps to the win32 SuspendThread function. (
180 * documentation about the the suspend count can be found here aswell )
181 * The suspend count is not increased if it is greater than
182 * MAXIMUM_SUSPEND_COUNT.
192 Status
= ObReferenceObjectByHandle(ThreadHandle
,
193 THREAD_SUSPEND_RESUME
,
198 if (!NT_SUCCESS(Status
))
203 Status
= PsSuspendThread(Thread
, &Count
);
204 if (!NT_SUCCESS(Status
))
206 ObDereferenceObject ((PVOID
)Thread
);
210 if (PreviousSuspendCount
!= NULL
)
212 *PreviousSuspendCount
= Count
;
215 ObDereferenceObject ((PVOID
)Thread
);
217 return STATUS_SUCCESS
;
221 PsInitialiseSuspendImplementation(VOID
)
223 ExInitializeFastMutex(&SuspendMutex
);