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/k... ============================================================================== --- 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=2... ============================================================================== --- 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)