revert my changes
Modified: trunk/reactos/ntoskrnl/ke/wait.c
_____
Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c 2005-03-22 23:34:08 UTC (rev
14274)
+++ trunk/reactos/ntoskrnl/ke/wait.c 2005-03-23 13:26:38 UTC (rev
14275)
@@ -250,7 +250,7 @@
/* It has a normal signal state, so unwait it and
return */
KiSatisfyObjectWait(CurrentObject, CurrentThread);
Status = STATUS_WAIT_0;
- break;
+ goto WaitDone;
} else {
@@ -285,7 +285,7 @@
/* Return a timeout */
Status = STATUS_TIMEOUT;
- break;
+ goto WaitDone;
}
/* Point to Timer Wait Block and Thread Timer */
@@ -311,7 +311,7 @@
/* Return a timeout if we couldn't insert the timer for
some reason */
Status = STATUS_TIMEOUT;
- break;
+ goto WaitDone;
}
}
@@ -344,6 +344,7 @@
} while (TRUE);
+WaitDone:
/* Release the Lock, we are done */
DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status:
%d\n", KeGetCurrentThread(), Status);
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
@@ -368,7 +369,7 @@
PKWAIT_BLOCK TimerWaitBlock;
PKTIMER ThreadTimer;
PKTHREAD CurrentThread = KeGetCurrentThread();
- BOOLEAN AllObjectsSignaled;
+ ULONG AllObjectsSignaled;
ULONG WaitIndex;
NTSTATUS Status;
NTSTATUS WaitStatus;
@@ -506,7 +507,7 @@
/* Satisfy their Waits and return to the caller */
KiSatisifyMultipleObjectWaits(WaitBlock);
Status = STATUS_WAIT_0;
- break;
+ goto WaitDone;
}
/* Make sure we can satisfy the Alertable request */
@@ -523,7 +524,7 @@
/* Return a timeout */
Status = STATUS_TIMEOUT;
- break;
+ goto WaitDone;
}
/* Point to Timer Wait Block and Thread Timer */
@@ -548,20 +549,22 @@
/* Return a timeout if we couldn't insert the timer for
some reason */
Status = STATUS_TIMEOUT;
- break;
+ goto WaitDone;
}
}
/* Insert into Object's Wait List*/
- for (WaitBlock = CurrentThread->WaitBlockList;
- WaitBlock != NULL;
- WaitBlock = WaitBlock->NextWaitBlock) {
+ WaitBlock = CurrentThread->WaitBlockList;
+ while (WaitBlock) {
/* Get the Current Object */
CurrentObject = WaitBlock->Object;
/* Link the Object to this Wait Block */
InsertTailList(&CurrentObject->WaitListHead,
&WaitBlock->WaitListEntry);
+
+ /* Move to the next Wait Block */
+ WaitBlock = WaitBlock->NextWaitBlock;
}
/* Handle Kernel Queues */
@@ -657,10 +660,8 @@
/* Loop the Wait Entries */
DPRINT("KiWaitTest for Object: %x\n", Object);
WaitList = &Object->WaitListHead;
-
- for (WaitEntry = WaitList->Flink;
- (WaitEntry != WaitList) && (Object->SignalState > 0);
- WaitEntry = WaitEntry->Flink) {
+ WaitEntry = WaitList->Flink;
+ while ((WaitEntry != WaitList) && (Object->SignalState > 0)) {
/* Get the current wait block */
CurrentWaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK,
WaitListEntry);
@@ -677,19 +678,21 @@
/* Everything must be satisfied */
DPRINT("Checking for a Wait All\n");
+ NextWaitBlock = CurrentWaitBlock->NextWaitBlock;
/* Loop first to make sure they are valid */
- for (NextWaitBlock = CurrentWaitBlock->NextWaitBlock;
- NextWaitBlock != NULL;
- NextWaitBlock = NextWaitBlock->NextWaitBlock) {
+ while (NextWaitBlock) {
/* Check if the object is signaled */
if (!KiIsObjectSignaled(Object,
CurrentWaitBlock->Thread)) {
/* It's not, move to the next one */
DPRINT1("One of the object is non-signaled,
sorry.\n");
- continue;
+ goto SkipUnwait;
}
+
+ /* Go to the next Wait block */
+ NextWaitBlock = NextWaitBlock->NextWaitBlock;
}
/* All the objects are signaled, we can satisfy */
@@ -701,6 +704,10 @@
/* All waits satisfied, unwait the thread */
DPRINT("Unwaiting the Thread\n");
KiAbortWaitThread(CurrentWaitBlock->Thread,
CurrentWaitBlock->WaitKey, Increment);
+
+SkipUnwait:
+ /* Next entry */
+ WaitEntry = WaitEntry->Flink;
}
DPRINT("Done\n");
@@ -721,14 +728,15 @@
/* Remove the Wait Blocks from the list */
DPRINT("Removing waits\n");
-
- for (WaitBlock = Thread->WaitBlockList;
- WaitBlock != NULL;
- WaitBlock = WaitBlock->NextWaitBlock) {
+ WaitBlock = Thread->WaitBlockList;
+ while (WaitBlock) {
/* Remove it */
DPRINT("Removing Waitblock: %x, %x\n", WaitBlock,
WaitBlock->NextWaitBlock);
RemoveEntryList(&WaitBlock->WaitListEntry);
+
+ /* Go to the next one */
+ WaitBlock = WaitBlock->NextWaitBlock;
};
/* Check if there's a Thread Timer */
updated an absolete comment
Modified: trunk/reactos/subsys/smss/initss.c
_____
Modified: trunk/reactos/subsys/smss/initss.c
--- trunk/reactos/subsys/smss/initss.c 2005-03-22 22:10:44 UTC (rev
14273)
+++ trunk/reactos/subsys/smss/initss.c 2005-03-22 23:34:08 UTC (rev
14274)
@@ -36,14 +36,10 @@
HANDLE hSmApiPort = (HANDLE) 0;
-/* TODO: this file should be totally rewritten
+/* TODO:
*
* a) look if a special option is set for smss.exe in
* HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Image File Execution Options
- *
- * d) make smss initialize Debug (DBGSS) and Windows (CSRSS) as
described
- * in the registry key Required="Debug Windows"
- * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\SubSystems
*/
/**********************************************************************
@@ -51,7 +47,7 @@
*
* DESCRIPTION
* Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
- * (programmatically). This also open hSmApiPort to be used
+ * (programmatically). This also opens hSmApiPort to be used
* in loading required subsystems.
*/
improve readability by removing obsolete gotos and for loops where
appropriate
Modified: trunk/reactos/ntoskrnl/ke/wait.c
_____
Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c 2005-03-22 07:29:02 UTC (rev
14266)
+++ trunk/reactos/ntoskrnl/ke/wait.c 2005-03-22 17:17:02 UTC (rev
14267)
@@ -250,7 +250,7 @@
/* It has a normal signal state, so unwait it and
return */
KiSatisfyObjectWait(CurrentObject, CurrentThread);
Status = STATUS_WAIT_0;
- goto WaitDone;
+ break;
} else {
@@ -285,7 +285,7 @@
/* Return a timeout */
Status = STATUS_TIMEOUT;
- goto WaitDone;
+ break;
}
/* Point to Timer Wait Block and Thread Timer */
@@ -311,7 +311,7 @@
/* Return a timeout if we couldn't insert the timer for
some reason */
Status = STATUS_TIMEOUT;
- goto WaitDone;
+ break;
}
}
@@ -344,7 +344,6 @@
} while (TRUE);
-WaitDone:
/* Release the Lock, we are done */
DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status:
%d\n", KeGetCurrentThread(), Status);
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
@@ -369,7 +368,7 @@
PKWAIT_BLOCK TimerWaitBlock;
PKTIMER ThreadTimer;
PKTHREAD CurrentThread = KeGetCurrentThread();
- ULONG AllObjectsSignaled;
+ BOOLEAN AllObjectsSignaled;
ULONG WaitIndex;
NTSTATUS Status;
NTSTATUS WaitStatus;
@@ -507,7 +506,7 @@
/* Satisfy their Waits and return to the caller */
KiSatisifyMultipleObjectWaits(WaitBlock);
Status = STATUS_WAIT_0;
- goto WaitDone;
+ break;
}
/* Make sure we can satisfy the Alertable request */
@@ -524,7 +523,7 @@
/* Return a timeout */
Status = STATUS_TIMEOUT;
- goto WaitDone;
+ break;
}
/* Point to Timer Wait Block and Thread Timer */
@@ -549,22 +548,20 @@
/* Return a timeout if we couldn't insert the timer for
some reason */
Status = STATUS_TIMEOUT;
- goto WaitDone;
+ break;
}
}
/* Insert into Object's Wait List*/
- WaitBlock = CurrentThread->WaitBlockList;
- while (WaitBlock) {
+ for (WaitBlock = CurrentThread->WaitBlockList;
+ WaitBlock != NULL;
+ WaitBlock = WaitBlock->NextWaitBlock) {
/* Get the Current Object */
CurrentObject = WaitBlock->Object;
/* Link the Object to this Wait Block */
InsertTailList(&CurrentObject->WaitListHead,
&WaitBlock->WaitListEntry);
-
- /* Move to the next Wait Block */
- WaitBlock = WaitBlock->NextWaitBlock;
}
/* Handle Kernel Queues */
@@ -660,8 +657,10 @@
/* Loop the Wait Entries */
DPRINT("KiWaitTest for Object: %x\n", Object);
WaitList = &Object->WaitListHead;
- WaitEntry = WaitList->Flink;
- while ((WaitEntry != WaitList) && (Object->SignalState > 0)) {
+
+ for (WaitEntry = WaitList->Flink;
+ (WaitEntry != WaitList) && (Object->SignalState > 0);
+ WaitEntry = WaitEntry->Flink) {
/* Get the current wait block */
CurrentWaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK,
WaitListEntry);
@@ -678,21 +677,19 @@
/* Everything must be satisfied */
DPRINT("Checking for a Wait All\n");
- NextWaitBlock = CurrentWaitBlock->NextWaitBlock;
/* Loop first to make sure they are valid */
- while (NextWaitBlock) {
+ for (NextWaitBlock = CurrentWaitBlock->NextWaitBlock;
+ NextWaitBlock != NULL;
+ NextWaitBlock = NextWaitBlock->NextWaitBlock) {
/* Check if the object is signaled */
if (!KiIsObjectSignaled(Object,
CurrentWaitBlock->Thread)) {
/* It's not, move to the next one */
DPRINT1("One of the object is non-signaled,
sorry.\n");
- goto SkipUnwait;
+ continue;
}
-
- /* Go to the next Wait block */
- NextWaitBlock = NextWaitBlock->NextWaitBlock;
}
/* All the objects are signaled, we can satisfy */
@@ -704,10 +701,6 @@
/* All waits satisfied, unwait the thread */
DPRINT("Unwaiting the Thread\n");
KiAbortWaitThread(CurrentWaitBlock->Thread,
CurrentWaitBlock->WaitKey, Increment);
-
-SkipUnwait:
- /* Next entry */
- WaitEntry = WaitEntry->Flink;
}
DPRINT("Done\n");
@@ -728,15 +721,14 @@
/* Remove the Wait Blocks from the list */
DPRINT("Removing waits\n");
- WaitBlock = Thread->WaitBlockList;
- while (WaitBlock) {
+
+ for (WaitBlock = Thread->WaitBlockList;
+ WaitBlock != NULL;
+ WaitBlock = WaitBlock->NextWaitBlock) {
/* Remove it */
DPRINT("Removing Waitblock: %x, %x\n", WaitBlock,
WaitBlock->NextWaitBlock);
RemoveEntryList(&WaitBlock->WaitListEntry);
-
- /* Go to the next one */
- WaitBlock = WaitBlock->NextWaitBlock;
};
/* Check if there's a Thread Timer */
fixed a few race conditions during thread/process termination leading to
dead-locks
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
Modified: trunk/reactos/ntoskrnl/ps/create.c
Modified: trunk/reactos/ntoskrnl/ps/kill.c
_____
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
--- trunk/reactos/ntoskrnl/include/internal/ps.h 2005-03-22
17:17:02 UTC (rev 14267)
+++ trunk/reactos/ntoskrnl/include/internal/ps.h 2005-03-22
17:32:15 UTC (rev 14268)
@@ -428,7 +428,6 @@
*/
MADDRESS_SPACE AddressSpace;
LIST_ENTRY ProcessListEntry;
- FAST_MUTEX TebLock;
PVOID TebBlock;
PVOID TebLastAllocated;
};
_____
Modified: trunk/reactos/ntoskrnl/ps/create.c
--- trunk/reactos/ntoskrnl/ps/create.c 2005-03-22 17:17:02 UTC (rev
14267)
+++ trunk/reactos/ntoskrnl/ps/create.c 2005-03-22 17:32:15 UTC (rev
14268)
@@ -166,7 +166,7 @@
else
{
Process = Thread->ThreadsProcess;
- ExAcquireFastMutex(&Process->TebLock);
+ PsLockProcess(Process, FALSE);
if (NULL == Process->TebBlock ||
Process->TebBlock == Process->TebLastAllocated)
{
@@ -180,7 +180,7 @@
PAGE_READWRITE);
if (! NT_SUCCESS(Status))
{
- ExReleaseFastMutex(&Process->TebLock);
+ PsUnlockProcess(Process);
DPRINT1("Failed to reserve virtual memory for TEB\n");
return Status;
}
@@ -199,7 +199,7 @@
return Status;
}
Process->TebLastAllocated = TebBase;
- ExReleaseFastMutex(&Process->TebLock);
+ PsUnlockProcess(Process);
}
DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize);
_____
Modified: trunk/reactos/ntoskrnl/ps/kill.c
--- trunk/reactos/ntoskrnl/ps/kill.c 2005-03-22 17:17:02 UTC (rev
14267)
+++ trunk/reactos/ntoskrnl/ps/kill.c 2005-03-22 17:32:15 UTC (rev
14268)
@@ -101,9 +101,9 @@
/* Make sure it didn't already terminate */
if (!Thread->HasTerminated) {
-
+
Thread->HasTerminated = TRUE;
-
+
/* Terminate it by APC */
PspTerminateThreadByPointer(Thread, ExitStatus);
}
@@ -143,7 +143,7 @@
PETHREAD Thread = (PETHREAD)ObjectBody;
PEPROCESS Process = Thread->ThreadsProcess;
- DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody);
+ DPRINT("PiDeleteThread(ObjectBody 0x%x, process
0x%x)\n",ObjectBody, Thread->ThreadsProcess);
/* Deassociate the Process */
Thread->ThreadsProcess = NULL;
@@ -179,12 +179,15 @@
PVOID TebBlock;
PTERMINATION_PORT TerminationPort;
- DPRINT("PsTerminateCurrentThread(ExitStatus %x), Current: 0x%x\n",
ExitStatus, PsGetCurrentThread());
+ DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus,
PsGetCurrentThread());
/* Get the Current Thread and Process */
CurrentThread = PsGetCurrentThread();
- CurrentThread->HasTerminated = TRUE;
CurrentProcess = CurrentThread->ThreadsProcess;
+
+ /* Set the Exit Status and Exit Time */
+ CurrentThread->ExitStatus = ExitStatus;
+ KeQuerySystemTime(&CurrentThread->ExitTime);
/* Can't terminate a thread if it attached another process */
if (KeIsAttachedProcess()) {
@@ -198,16 +201,15 @@
/* Lower to Passive Level */
KeLowerIrql(PASSIVE_LEVEL);
+ /* Lock the Process before we modify its thread entries */
+ PsLockProcess(CurrentProcess, FALSE);
+
+ /* wake up the thread so we don't deadlock on PsLockProcess */
+ KeForceResumeThread(&CurrentThread->Tcb);
+
/* Run Thread Notify Routines before we desintegrate the thread */
PspRunCreateThreadNotifyRoutines(CurrentThread, FALSE);
-
- /* Set the Exit Status and Exit Time */
- CurrentThread->ExitStatus = ExitStatus;
- KeQuerySystemTime(&CurrentThread->ExitTime);
- /* Lock the Process before we modify its thread entries */
- PsLockProcess(CurrentProcess, FALSE);
-
/* Remove the thread from the thread list of its process */
RemoveEntryList(&CurrentThread->ThreadListEntry);
Last = IsListEmpty(&CurrentProcess->ThreadListHead);
@@ -250,36 +252,31 @@
PsTerminateWin32Thread(CurrentThread);
if (Last) PsTerminateWin32Process(CurrentProcess);
- /* Cancel I/O for the thread. */
- IoCancelThreadIo(CurrentThread);
-
/* Rundown Registry Notifications. TODO (refers to NtChangeNotify,
not Cm callbacks) */
//CmNotifyRunDown(CurrentThread);
-
+
/* Free the TEB */
if(CurrentThread->Tcb.Teb) {
-
+
DPRINT("Decommit teb at %p\n", CurrentThread->Tcb.Teb);
- ExAcquireFastMutex(&CurrentProcess->TebLock);
TebBlock = MM_ROUND_DOWN(CurrentThread->Tcb.Teb,
MM_VIRTMEM_GRANULARITY);
-
+
ZwFreeVirtualMemory(NtCurrentProcess(),
(PVOID *)&CurrentThread->Tcb.Teb,
&Length,
MEM_DECOMMIT);
-
+
DPRINT("teb %p, TebBlock %p\n", CurrentThread->Tcb.Teb,
TebBlock);
-
+
if (TebBlock != CurrentProcess->TebBlock ||
CurrentProcess->TebBlock ==
CurrentProcess->TebLastAllocated) {
-
+
MmLockAddressSpace(&CurrentProcess->AddressSpace);
MmReleaseMemoryAreaIfDecommitted(CurrentProcess,
&CurrentProcess->AddressSpace, TebBlock);
MmUnlockAddressSpace(&CurrentProcess->AddressSpace);
}
-
+
CurrentThread->Tcb.Teb = NULL;
- ExReleaseFastMutex(&CurrentProcess->TebLock);
}
/* The last Thread shuts down the Process */
@@ -288,6 +285,9 @@
/* Unlock the Process */
PsUnlockProcess(CurrentProcess);
+ /* Cancel I/O for the thread. */
+ IoCancelThreadIo(CurrentThread);
+
/* Rundown Timers */
ExTimerRundown();
KeCancelTimer(&CurrentThread->Tcb.Timer);
@@ -318,7 +318,7 @@
{
NTSTATUS ExitStatus = (NTSTATUS)Apc->NormalContext;
- DPRINT("PsExitSpecialApc called: 0x%x\n", PsGetCurrentThread());
+ DPRINT("PsExitSpecialApc called: 0x%x (proc: 0x%x)\n",
PsGetCurrentThread(), PsGetCurrentProcess());
/* Free the APC */
ExFreePool(Apc);
@@ -396,7 +396,7 @@
STDCALL
PspExitProcess(PEPROCESS Process)
{
- DPRINT("PspExitProcess\n");
+ DPRINT("PspExitProcess 0x%x\n", Process);
PspRunCreateProcessNotifyRoutines(Process, FALSE);
@@ -421,25 +421,31 @@
{
NTSTATUS Status;
PEPROCESS Process;
+ PETHREAD CurrentThread;
+ BOOLEAN KillByHandle;
PAGED_CODE();
DPRINT("NtTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
ProcessHandle, ExitStatus);
+ KillByHandle = (ProcessHandle != NULL);
+
/* Get the Process Object */
- Status = ObReferenceObjectByHandle(ProcessHandle,
+ Status = ObReferenceObjectByHandle((KillByHandle ? ProcessHandle :
NtCurrentProcess()),
PROCESS_TERMINATE,
PsProcessType,
KeGetPreviousMode(),
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1("Invalid handle to Process\n");
return(Status);
}
+ CurrentThread = PsGetCurrentThread();
+
PsLockProcess(Process, FALSE);
if(Process->ExitTime.QuadPart != 0)
@@ -450,36 +456,43 @@
/* Terminate all the Process's Threads */
PspTerminateProcessThreads(Process, ExitStatus);
-
- /* Only master thread remains... kill it off */
- if (PsGetCurrentThread()->ThreadsProcess == Process) {
-
+
+ /* only kill the calling thread if it either passed a process
handle or
+ NtCurrentProcess() */
+ if (KillByHandle) {
+
/* set the exit time as we're about to release the process lock
before
we kill ourselves to prevent threads outside of our process
trying
to kill us */
KeQuerySystemTime(&Process->ExitTime);
-
- PsUnlockProcess(Process);
-
- /* we can safely dereference the process because the current
thread
- holds a reference to it until it gets reaped */
- ObDereferenceObject(Process);
-
- /* now the other threads get a chance to terminate, we don't
wait but
- just kill ourselves right now. The process will be run down
when the
- last thread terminates */
- PspExitThread(ExitStatus);
-
- /* we should never reach this point! */
- KEBUGCHECK(0);
+ /* Only master thread remains... kill it off */
+ if (CurrentThread->ThreadsProcess == Process) {
+
+ /* mark our thread as terminating so attempts to terminate
it, when
+ unlocking the process, fail */
+ CurrentThread->HasTerminated = TRUE;
+
+ PsUnlockProcess(Process);
+
+ /* we can safely dereference the process because the
current thread
+ holds a reference to it until it gets reaped */
+ ObDereferenceObject(Process);
+
+ /* now the other threads get a chance to terminate, we
don't wait but
+ just kill ourselves right now. The process will be run
down when the
+ last thread terminates */
+
+ PspExitThread(ExitStatus);
+
+ /* we should never reach this point! */
+ KEBUGCHECK(0);
+ }
}
- else
- {
- /* unlock and dereference the process so the threads can kill
themselves */
- PsUnlockProcess(Process);
- ObDereferenceObject(Process);
- }
+
+ /* unlock and dereference the process so the threads can kill
themselves */
+ PsUnlockProcess(Process);
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
@@ -501,7 +514,7 @@
KeGetPreviousMode(),
(PVOID*)&Thread,
NULL);
- if (Status != STATUS_SUCCESS) {
+ if (!NT_SUCCESS(Status)) {
DPRINT1("Could not reference thread object\n");
return(Status);
@@ -518,15 +531,27 @@
/* Check to see if we're running in the same thread */
if (Thread != PsGetCurrentThread()) {
- /* This isn't our thread, check if it's terminated already */
+ /* we need to lock the process to make sure it's not already
terminating */
+ PsLockProcess(Thread->ThreadsProcess, FALSE);
+
+ /* This isn't our thread, terminate it if not already done */
if (!Thread->HasTerminated) {
+ Thread->HasTerminated = TRUE;
+
/* Terminate it */
PspTerminateThreadByPointer(Thread, ExitStatus);
- }
+ }
+ PsUnlockProcess(Thread->ThreadsProcess);
+
+ /* Dereference the Thread and return */
+ ObDereferenceObject(Thread);
+
} else {
+ Thread->HasTerminated = TRUE;
+
/* it's safe to dereference thread, there's at least the
keep-alive
reference which will be removed by the thread reaper causing
the
thread to be finally destroyed */
@@ -539,8 +564,6 @@
KEBUGCHECK(0);
}
- /* Dereference the Thread and return */
- ObDereferenceObject(Thread);
return(STATUS_SUCCESS);
}