Author: ion
Date: Mon Oct 23 00:52:13 2006
New Revision: 24613
URL:
http://svn.reactos.org/svn/reactos?rev=24613&view=rev
Log:
- Implement KeThawAllThreads based on KeFreezeAllThreads.
- Fix a bug in KeFreezeAllThreads which was causing us never to actually parse the next
flink.
- Fix a bug in KeFreezeAllThreads which was causing us never to leave the critical region
we entered at the beginning.
Modified:
trunk/reactos/ntoskrnl/include/internal/ke.h
trunk/reactos/ntoskrnl/ke/thrdobj.c
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Mon Oct 23 00:52:13 2006
@@ -528,6 +528,12 @@
VOID
NTAPI
+KeThawAllThreads(
+ VOID
+);
+
+VOID
+NTAPI
KeFreezeAllThreads(
VOID
);
Modified: trunk/reactos/ntoskrnl/ke/thrdobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/thrdobj.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/thrdobj.c (original)
+++ trunk/reactos/ntoskrnl/ke/thrdobj.c Mon Oct 23 00:52:13 2006
@@ -304,11 +304,17 @@
/* Release the APC lock */
KiReleaseApcLockFromDpcLevel(&ApcLock);
+
+ /* Move to the next thread */
+ NextEntry = NextEntry->Flink;
}
/* Release the process lock and exit the dispatcher */
KiReleaseProcessLock(&LockHandle);
KiExitDispatcher(LockHandle.OldIrql);
+
+ /* Leave the critical region */
+ KeLeaveCriticalRegion();
}
ULONG
@@ -573,6 +579,71 @@
return PreviousCount;
}
+VOID
+NTAPI
+KeThawAllThreads(VOID)
+{
+ KLOCK_QUEUE_HANDLE LockHandle, ApcLock;
+ PKTHREAD Current, CurrentThread = KeGetCurrentThread();
+ PKPROCESS Process = CurrentThread->ApcState.Process;
+ PLIST_ENTRY ListHead, NextEntry;
+ LONG OldCount;
+ ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+
+ /* Lock the process */
+ KiAcquireProcessLock(Process, &LockHandle);
+
+ /* Enter a critical region */
+ KeEnterCriticalRegion();
+
+ /* Loop the Process's Threads */
+ ListHead = &Process->ThreadListHead;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ /* Get the current thread */
+ Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
+
+ /* Lock it */
+ KiAcquireApcLockAtDpcLevel(Current, &ApcLock);
+
+ /* Make sure we are frozen */
+ OldCount = Current->FreezeCount;
+ if (OldCount)
+ {
+ /* Decrease the freeze count */
+ Current->FreezeCount--;
+
+ /* Check if both counts are zero now */
+ if (!(Current->SuspendCount) && (!Current->FreezeCount))
+ {
+ /* Lock the dispatcher */
+ KiAcquireDispatcherLockAtDpcLevel();
+
+ /* Signal the suspend semaphore and wake it */
+ Current->SuspendSemaphore.Header.SignalState++;
+ KiWaitTest(&Current->SuspendSemaphore, 1);
+
+ /* Unlock the dispatcher */
+ KiReleaseDispatcherLockFromDpcLevel();
+ }
+ }
+
+ /* Release the APC lock */
+ KiReleaseApcLockFromDpcLevel(&ApcLock);
+
+ /* Go to the next one */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Release the process lock and exit the dispatcher */
+ KiReleaseProcessLock(&LockHandle);
+ KiExitDispatcher(LockHandle.OldIrql);
+
+ /* Leave the critical region */
+ KeLeaveCriticalRegion();
+}
+
BOOLEAN
NTAPI
KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)