Author: ion
Date: Fri Jul 14 06:26:44 2006
New Revision: 23057
URL: http://svn.reactos.org/svn/reactos?rev=23057&view=rev
Log:
- Fix a serious bug in Kernel Queues. A condition existed where an inserted kernel queue with a timeout would crash the system once the thread waiting on it had its wait aborted or completed.
- Thanks a lot to Thomas for his brutal test application which allowed me to discover this bug and the bugs addressed in the previous commits (related to the wait list and thread scheduler list corruption).
Modified:
trunk/reactos/ntoskrnl/ke/kthread.c
trunk/reactos/ntoskrnl/ke/queue.c
trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/kthread.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/kthread.c (original)
+++ trunk/reactos/ntoskrnl/ke/kthread.c Fri Jul 14 06:26:44 2006
@@ -764,7 +764,7 @@
/* Initialize the Suspend Semaphore */
KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
- /* FIXME OPTIMIZATION OF DOOM. DO NOT ENABLE FIXME */
+ /* Setup the timer */
Timer = &Thread->Timer;
KeInitializeTimer(Timer);
TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
Modified: trunk/reactos/ntoskrnl/ke/queue.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/queue.c?rev=23…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/queue.c (original)
+++ trunk/reactos/ntoskrnl/ke/queue.c Fri Jul 14 06:26:44 2006
@@ -390,6 +390,10 @@
&WaitBlock->WaitListEntry;
Timer->Header.WaitListHead.Blink =
&WaitBlock->WaitListEntry;
+ WaitBlock->WaitListEntry.Flink =
+ &Timer->Header.WaitListHead;
+ WaitBlock->WaitListEntry.Blink =
+ &Timer->Header.WaitListHead;
/* Create Timer */
KiInsertTimer(Timer, *Timeout);
@@ -427,8 +431,8 @@
/* Check if we had a timeout */
if (Timeout)
{
- /* FIXME: Fixup interval */
- DPRINT1("FIXME!!!\n");
+ DPRINT1("If you see this message, contact Alex ASAP\n");
+ KEBUGCHECK(0);
}
}
Modified: trunk/reactos/ntoskrnl/ke/wait.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/wait.c?rev=230…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/wait.c (original)
+++ trunk/reactos/ntoskrnl/ke/wait.c Fri Jul 14 06:26:44 2006
@@ -360,7 +360,9 @@
return WaitStatus;
}
- /* FIXME: Fixup interval */
+ /* Check if we had a timeout */
+ DPRINT1("If you see this message, contact Alex ASAP\n");
+ KEBUGCHECK(0);
}
/* Acquire again the lock */
@@ -533,7 +535,8 @@
/* Check if we had a timeout */
if (Timeout)
{
- /* FIXME: Fixup interval */
+ DPRINT1("If you see this message, contact Alex ASAP\n");
+ KEBUGCHECK(0);
}
}
@@ -813,7 +816,8 @@
/* Check if we had a timeout */
if (Timeout)
{
- /* FIXME: Fixup interval */
+ DPRINT1("If you see this message, contact Alex ASAP\n");
+ KEBUGCHECK(0);
}
/* Acquire again the lock */
Author: ion
Date: Fri Jul 14 05:03:27 2006
New Revision: 23056
URL: http://svn.reactos.org/svn/reactos?rev=23056&view=rev
Log:
- Add KiCheckThreadStackSwap and KiAddThreadToWaitList macros
- Initialize PRCBs' Wait Lists
- Fix a ghastly implementation fault where the the queue code was correctly removing the thread from its wait list, but where this wait list was actually connected to the _SCHEDULER_ and ended up removing a thread behind its back, causing bizarre issues and w3seek's ASSERT(State == Ready) bug. Fixed this by using the macros above and PRCB Wait List and properly inserting a waiting thread into that list, and then removing it when unblocking it or removing a queue.
Modified:
trunk/reactos/ntoskrnl/include/internal/ke_x.h
trunk/reactos/ntoskrnl/ke/i386/kernel.c
trunk/reactos/ntoskrnl/ke/kthread.c
trunk/reactos/ntoskrnl/ke/queue.c
trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/include/internal/ke_x.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke_x.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke_x.h Fri Jul 14 05:03:27 2006
@@ -156,6 +156,40 @@
}
//
+// Determines wether a thread should be added to the wait list
+//
+#define KiCheckThreadStackSwap(WaitMode, Thread, Swappable) \
+{ \
+ /* Check the required conditions */ \
+ if ((WaitMode != KernelMode) && \
+ (Thread->EnableStackSwap) && \
+ (Thread->Priority >= (LOW_REALTIME_PRIORITY + 9))) \
+ { \
+ /* We are go for swap */ \
+ Swappable = TRUE; \
+ } \
+ else \
+ { \
+ /* Don't swap the thread */ \
+ Swappable = FALSE; \
+ } \
+}
+
+//
+// Adds a thread to the wait list
+//
+#define KiAddThreadToWaitList(Thread, Swappable) \
+{ \
+ /* Make sure it's swappable */ \
+ if (Swappable) \
+ { \
+ /* Insert it into the PRCB's List */ \
+ InsertTailList(&KeGetCurrentPrcb()->WaitListHead, \
+ &Thread->WaitListEntry); \
+ } \
+}
+
+//
// Rules for checking alertability:
// - For Alertable waits ONLY:
// * We don't wait and return STATUS_ALERTED if the thread is alerted
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/kernel.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/kernel.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/kernel.c Fri Jul 14 05:03:27 2006
@@ -252,6 +252,7 @@
KiCheckFPU();
KeInitDpc(Pcr->Prcb);
+ InitializeListHead(&Pcr->PrcbData.WaitListHead);
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL)
{
@@ -332,6 +333,7 @@
KPCR->NtTib.ExceptionList = (PVOID)-1;
KeInitDpc(KPCR->Prcb);
+ InitializeListHead(&KPCR->PrcbData.WaitListHead);
KeInitExceptions ();
KeInitInterrupts ();
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/kthread.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/kthread.c (original)
+++ trunk/reactos/ntoskrnl/ke/kthread.c Fri Jul 14 05:03:27 2006
@@ -83,7 +83,7 @@
if (current->State != Ready) {
- DPRINT1("%d/%d\n", ¤t, current->State);
+ DPRINT1("%p/%d\n", current, current->State);
}
ASSERT(current->State == Ready);
Modified: trunk/reactos/ntoskrnl/ke/queue.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/queue.c?rev=23…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/queue.c (original)
+++ trunk/reactos/ntoskrnl/ke/queue.c Fri Jul 14 05:03:27 2006
@@ -102,7 +102,7 @@
/* Remove the queue from the thread's wait list */
Thread->WaitStatus = (NTSTATUS)Entry;
- RemoveEntryList(&Thread->WaitListEntry);
+ if (Thread->WaitListEntry.Flink) RemoveEntryList(&Thread->WaitListEntry);
Thread->WaitReason = 0;
/* Increase the active threads and set the status*/
@@ -248,6 +248,7 @@
PKQUEUE PreviousQueue;
PKWAIT_BLOCK WaitBlock;
PKTIMER Timer;
+ BOOLEAN Swappable;
ASSERT_QUEUE(Queue);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
@@ -354,6 +355,10 @@
WaitBlock->Thread = Thread;
Thread->WaitStatus = STATUS_WAIT_0;
+ /* Check if we can swap the thread's stack */
+ Thread->WaitListEntry.Flink = NULL;
+ KiCheckThreadStackSwap(WaitMode, Thread, Swappable);
+
/* We need to wait for the object... check for a timeout */
if (Timeout)
{
@@ -406,6 +411,7 @@
Thread->State = Waiting;
/* Find a new thread to run */
+ KiAddThreadToWaitList(Thread, Swappable);
Status = KiSwapThread();
/* Reset the wait reason */
Modified: trunk/reactos/ntoskrnl/ke/wait.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/wait.c?rev=230…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/wait.c (original)
+++ trunk/reactos/ntoskrnl/ke/wait.c Fri Jul 14 05:03:27 2006
@@ -143,8 +143,8 @@
WaitBlock = WaitBlock->NextWaitBlock;
} while (WaitBlock != Thread->WaitBlockList);
- /* FIXME: Remove the thread from the wait list! */
- //RemoveEntryList(&Thread->WaitListEntry);
+ /* Remove the thread from the wait list! */
+ if (Thread->WaitListEntry.Flink) RemoveEntryList(&Thread->WaitListEntry);
/* Check if there's a Thread Timer */
Timer = &Thread->Timer;
@@ -274,6 +274,7 @@
PKTIMER ThreadTimer;
PKTHREAD CurrentThread = KeGetCurrentThread();
NTSTATUS WaitStatus = STATUS_SUCCESS;
+ BOOLEAN Swappable;
/* Check if the lock is already held */
if (CurrentThread->WaitNext)
@@ -305,6 +306,10 @@
{
/* Check if we can do an alertable wait, if requested */
KiCheckAlertability();
+
+ /* Check if we can swap the thread's stack */
+ CurrentThread->WaitListEntry.Flink = NULL;
+ KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable);
/* Set status */
CurrentThread->WaitStatus = STATUS_WAIT_0;
@@ -341,6 +346,7 @@
CurrentThread->State = Waiting;
/* Find a new thread to run */
+ KiAddThreadToWaitList(CurrentThread, Swappable);
WaitStatus = KiSwapThread();
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
@@ -383,6 +389,7 @@
PKTIMER ThreadTimer;
PKTHREAD CurrentThread = KeGetCurrentThread();
NTSTATUS WaitStatus = STATUS_SUCCESS;
+ BOOLEAN Swappable;
/* Check if the lock is already held */
if (CurrentThread->WaitNext)
@@ -461,6 +468,10 @@
/* Make sure we can satisfy the Alertable request */
KiCheckAlertability();
+ /* Check if we can swap the thread's stack */
+ CurrentThread->WaitListEntry.Flink = NULL;
+ KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable);
+
/* Enable the Timeout Timer if there was any specified */
if (Timeout)
{
@@ -512,6 +523,7 @@
CurrentThread->State = Waiting;
/* Find a new thread to run */
+ KiAddThreadToWaitList(CurrentThread, Swappable);
WaitStatus = KiSwapThread();
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
@@ -564,6 +576,7 @@
ULONG AllObjectsSignaled;
ULONG WaitIndex;
NTSTATUS WaitStatus = STATUS_SUCCESS;
+ BOOLEAN Swappable;
/* Set the Current Thread */
CurrentThread = KeGetCurrentThread();
@@ -727,6 +740,10 @@
/* Make sure we can satisfy the Alertable request */
KiCheckAlertability();
+ /* Check if we can swap the thread's stack */
+ CurrentThread->WaitListEntry.Flink = NULL;
+ KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable);
+
/* Enable the Timeout Timer if there was any specified */
if (Timeout)
{
@@ -786,6 +803,7 @@
CurrentThread->State = Waiting;
/* Find a new thread to run */
+ KiAddThreadToWaitList(CurrentThread, Swappable);
WaitStatus = KiSwapThread();
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
Author: greatlrd
Date: Fri Jul 14 02:42:40 2006
New Revision: 23054
URL: http://svn.reactos.org/svn/reactos?rev=23054&view=rev
Log:
Activate screensaver for bootcd
rember fullpath should be c:\reactos\system32\matrix.scr but we use matrix.scr as key path for getting this working on livecd.
But the desk.cpl apps should save full path to it. (and it does it in windows and reactos before ros cm broken it did in ros).
Modified:
trunk/reactos/boot/bootdata/hivedef.inf
Modified: trunk/reactos/boot/bootdata/hivedef.inf
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/hivedef.inf?…
==============================================================================
--- trunk/reactos/boot/bootdata/hivedef.inf (original)
+++ trunk/reactos/boot/bootdata/hivedef.inf Fri Jul 14 02:42:40 2006
@@ -10,6 +10,7 @@
HKCU,"Control Panel\Desktop","DragFullWindows",0x00000002,"0"
HKCU,"Control Panel\Desktop","PaintDesktopVersion",0x00010001,"0"
HKCU,"Control Panel\Desktop","HungAppTimeout",0x00000002,"5000"
+HKCU,"Control Panel\Desktop","SCRNSAVE.EXE",0x00000000,"matrix.scr"
HKCU,"Control Panel\Desktop","WaitToKillAppTimeout",0x00000002,"20000"
HKCU,"Control Panel\Desktop","Wallpaper",0x00000000,""
HKCU,"Control Panel\International",,0x00000012