From c8f27683f08cb2533d52515eddd30bc0433a2d55 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Tue, 30 Dec 2003 00:12:47 +0000 Subject: [PATCH] Screw branches, I'm committing to HEAD. Life is too short svn path=/trunk/; revision=7320 --- reactos/lib/kernel32/makefile | 5 +- reactos/lib/kernel32/thread/thread.c | 3 +- reactos/ntoskrnl/include/internal/ps.h | 10 ++- reactos/ntoskrnl/ps/create.c | 58 +++++------------ reactos/ntoskrnl/ps/kill.c | 88 +++++++++++--------------- reactos/ntoskrnl/ps/process.c | 65 +++++-------------- 6 files changed, 84 insertions(+), 145 deletions(-) diff --git a/reactos/lib/kernel32/makefile b/reactos/lib/kernel32/makefile index 018959b638b..7904a868c82 100644 --- a/reactos/lib/kernel32/makefile +++ b/reactos/lib/kernel32/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.71 2003/09/20 23:37:56 weiden Exp $ +# $Id: makefile,v 1.72 2003/12/30 00:12:47 hyperion Exp $ PATH_TO_TOP = ../.. @@ -51,7 +51,8 @@ THREAD_OBJECTS = \ thread/fls.o THREAD_I386_OBJECTS = \ - thread/i386/fiber.o + thread/i386/fiber.o \ + thread/i386/exit.o PROCESS_OBJECTS = \ process/proc.o \ diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index a5422c19028..c14710d7f7d 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.45 2003/09/12 17:51:47 vizzini Exp $ +/* $Id: thread.c,v 1.46 2003/12/30 00:12:47 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -8,6 +8,7 @@ * Tls functions are modified from WINE * UPDATE HISTORY: * Created 01/11/98 + * */ /* INCLUDES ******************************************************************/ diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 0a9b2affc14..1914ee79387 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: ps.h,v 1.55 2003/12/14 18:02:34 hbirr Exp $ +/* $Id: ps.h,v 1.56 2003/12/30 00:12:47 hyperion Exp $ * * FILE: ntoskrnl/ke/kthread.c * PURPOSE: Process manager definitions @@ -543,6 +543,14 @@ PsTerminateWin32Thread (PETHREAD Thread); VOID PsInitialiseW32Call(VOID); +VOID +STDCALL +PspRunCreateThreadNotifyRoutines(PETHREAD, BOOLEAN); + +VOID +STDCALL +PspRunCreateProcessNotifyRoutines(PEPROCESS, BOOLEAN); + #endif /* ASSEMBLER */ #endif /* __INCLUDE_INTERNAL_PS_H */ diff --git a/reactos/ntoskrnl/ps/create.c b/reactos/ntoskrnl/ps/create.c index 846dc160409..a34b6c105c6 100644 --- a/reactos/ntoskrnl/ps/create.c +++ b/reactos/ntoskrnl/ps/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.67 2003/09/25 20:08:36 ekohl Exp $ +/* $Id: create.c,v 1.68 2003/12/30 00:12:47 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -288,38 +288,19 @@ PiDeleteThread(PVOID ObjectBody) { KIRQL oldIrql; PETHREAD Thread; - ULONG i; - PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT]; - ULONG NotifyRoutineCount; Thread = (PETHREAD)ObjectBody; DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody); - /* Terminate Win32 thread */ - PsTerminateWin32Thread (Thread); - ObDereferenceObject(Thread->ThreadsProcess); Thread->ThreadsProcess = NULL; KeAcquireSpinLock(&PiThreadListLock, &oldIrql); - for (i = 0; i < PiThreadNotifyRoutineCount; i++) - { - NotifyRoutine[i] = PiThreadNotifyRoutine[i]; - } - NotifyRoutineCount = PiThreadNotifyRoutineCount; PiNrThreads--; RemoveEntryList(&Thread->Tcb.ThreadListEntry); KeReleaseSpinLock(&PiThreadListLock, oldIrql); - for (i = 0; i < NotifyRoutineCount; i++) - { - //must be called below DISPATCH_LVL - NotifyRoutine[i](Thread->Cid.UniqueProcess, - Thread->Cid.UniqueThread, - FALSE); - } - KeReleaseThread(Thread); DPRINT("PiDeleteThread() finished\n"); } @@ -336,9 +317,6 @@ PsInitializeThread(HANDLE ProcessHandle, NTSTATUS Status; KIRQL oldIrql; PEPROCESS Process; - ULONG i; - ULONG NotifyRoutineCount; - PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT]; /* * Reference process @@ -421,24 +399,11 @@ PsInitializeThread(HANDLE ProcessHandle, KeAcquireSpinLock(&PiThreadListLock, &oldIrql); InsertTailList(&PiThreadListHead, &Thread->Tcb.ThreadListEntry); - for (i = 0; i < PiThreadNotifyRoutineCount; i++) - { - NotifyRoutine[i] = PiThreadNotifyRoutine[i]; - } - NotifyRoutineCount = PiThreadNotifyRoutineCount; KeReleaseSpinLock(&PiThreadListLock, oldIrql); Thread->Tcb.BasePriority = Thread->ThreadsProcess->Pcb.BasePriority; Thread->Tcb.Priority = Thread->Tcb.BasePriority; - for (i = 0; i < NotifyRoutineCount; i++) - { - //must be called below DISPATCH_LVL - NotifyRoutine[i](Thread->Cid.UniqueProcess, - Thread->Cid.UniqueThread, - TRUE); - } - return(STATUS_SUCCESS); } @@ -735,6 +700,20 @@ PsCreateSystemThread(PHANDLE ThreadHandle, return(STATUS_SUCCESS); } +VOID +STDCALL +PspRunCreateThreadNotifyRoutines +( + PETHREAD CurrentThread, + BOOLEAN Create +) +{ + ULONG i; + CLIENT_ID Cid = CurrentThread->Cid; + + for(i = 0; i < PiThreadNotifyRoutineCount; ++ i) + PiThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create); +} /* * @implemented @@ -742,18 +721,13 @@ PsCreateSystemThread(PHANDLE ThreadHandle, NTSTATUS STDCALL PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine) { - KIRQL oldIrql; - - KeAcquireSpinLock(&PiThreadListLock, &oldIrql); - if (PiThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT) + if (PiThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT) { - KeReleaseSpinLock(&PiThreadListLock, oldIrql); return(STATUS_INSUFFICIENT_RESOURCES); } PiThreadNotifyRoutine[PiThreadNotifyRoutineCount] = NotifyRoutine; PiThreadNotifyRoutineCount++; - KeReleaseSpinLock(&PiThreadListLock, oldIrql); return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index 055af71ac44..3ed55a66760 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -1,4 +1,4 @@ -/* $Id: kill.c,v 1.67 2003/11/02 03:09:06 ekohl Exp $ +/* $Id: kill.c,v 1.68 2003/12/30 00:12:47 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -95,52 +95,18 @@ PsReapThreads(VOID) if (current->Tcb.State == THREAD_STATE_TERMINATED_1) { - PEPROCESS Process = current->ThreadsProcess; - NTSTATUS Status = current->ExitStatus; - BOOLEAN Last; - PiNrThreadsAwaitingReaping--; current->Tcb.State = THREAD_STATE_TERMINATED_2; - RemoveEntryList(¤t->Tcb.ProcessThreadListEntry); - Last = IsListEmpty(&Process->ThreadListHead); - KeReleaseSpinLock(&PiThreadListLock, oldIrql); - - if (Last) - { - PiTerminateProcess(Process, Status); - } - else - { - if (current->Tcb.Teb) - { - /* If this is not the last thread for the process then free the memory - from user stack and teb. */ - NTSTATUS Status; - ULONG Length; - ULONG Offset; - PVOID DeallocationStack; - HANDLE ProcessHandle; - Status = ObCreateHandle(PsGetCurrentProcess(), Process, PROCESS_ALL_ACCESS, FALSE, &ProcessHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObCreateHandle failed, status = %x\n", Status); - KEBUGCHECK(0); - } - Offset = FIELD_OFFSET(TEB, DeallocationStack); - Length = 0; - NtReadVirtualMemory(ProcessHandle, (PVOID)current->Tcb.Teb + Offset, - (PVOID)&DeallocationStack, sizeof(PVOID), &Length); - if (DeallocationStack && Length == sizeof(PVOID)) - { - NtFreeVirtualMemory(ProcessHandle, &DeallocationStack, &Length, MEM_RELEASE); - } - Length = PAGE_SIZE; - NtFreeVirtualMemory(ProcessHandle, (PVOID*)¤t->Tcb.Teb, &Length, MEM_RELEASE); - NtClose(ProcessHandle); - } - } + + /* + An unbelievably complex chain of events would cause a system crash + if PiThreadListLock was still held when the thread object is about + to be destroyed + */ + KeReleaseSpinLock(&PiThreadListLock, oldIrql); ObDereferenceObject(current); - KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); + current_entry = PiThreadListHead.Flink; } } @@ -155,23 +121,35 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus) { KIRQL oldIrql; PETHREAD CurrentThread; - PKTHREAD Thread; PLIST_ENTRY current_entry; PKMUTANT Mutant; + BOOLEAN Last; + PEPROCESS CurrentProcess; + + KeLowerIrql(PASSIVE_LEVEL); + + CurrentThread = PsGetCurrentThread(); + CurrentProcess = CurrentThread->ThreadsProcess; KeAcquireSpinLock(&PiThreadListLock, &oldIrql); - CurrentThread = PsGetCurrentThread(); DPRINT("terminating %x\n",CurrentThread); CurrentThread->ExitStatus = ExitStatus; - Thread = KeGetCurrentThread(); - KeCancelTimer(&Thread->Timer); + KeCancelTimer(&CurrentThread->Tcb.Timer); + + /* Remove the thread from the thread list of its process */ + RemoveEntryList(&CurrentThread->Tcb.ProcessThreadListEntry); + Last = IsListEmpty(&CurrentProcess->ThreadListHead); + KeReleaseSpinLock(&PiThreadListLock, oldIrql); + PspRunCreateThreadNotifyRoutines(CurrentThread, FALSE); + PsTerminateWin32Thread(CurrentThread); + /* abandon all owned mutants */ - current_entry = Thread->MutantListHead.Flink; - while (current_entry != &Thread->MutantListHead) + current_entry = CurrentThread->Tcb.MutantListHead.Flink; + while (current_entry != &CurrentThread->Tcb.MutantListHead) { Mutant = CONTAINING_RECORD(current_entry, KMUTANT, MutantListEntry); @@ -179,7 +157,7 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus) MUTANT_INCREMENT, TRUE, FALSE); - current_entry = Thread->MutantListHead.Flink; + current_entry = CurrentThread->Tcb.MutantListHead.Flink; } oldIrql = KeAcquireDispatcherDatabaseLock(); @@ -187,6 +165,14 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus) KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); KeReleaseDispatcherDatabaseLock (oldIrql); + /* The last thread shall close the door on exit */ + if(Last) + { + PspRunCreateProcessNotifyRoutines(CurrentProcess, FALSE); + PsTerminateWin32Process(CurrentProcess); + PiTerminateProcess(CurrentProcess, ExitStatus); + } + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); ExpSwapThreadEventPair(CurrentThread, NULL); /* Release the associated eventpair object, if there was one */ diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index e48ae5948ad..bb4b0c5ee02 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.120 2003/11/17 02:12:51 hyperion Exp $ +/* $Id: process.c,v 1.121 2003/12/30 00:12:47 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -329,9 +329,6 @@ VOID STDCALL PiDeleteProcessWorker(PVOID pContext) { KIRQL oldIrql; - ULONG i; - PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT]; - ULONG NotifyRoutineCount; PDEL_CONTEXT Context; PEPROCESS CurrentProcess; PEPROCESS Process; @@ -347,29 +344,10 @@ PiDeleteProcessWorker(PVOID pContext) KeAttachProcess(Process); } - /* Terminate Win32 Process */ - PsTerminateWin32Process (Process); - KeAcquireSpinLock(&PsProcessListLock, &oldIrql); - NotifyRoutineCount = 0; - for (i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; i++) - { - if (PiProcessNotifyRoutine[i]) - { - NotifyRoutine[NotifyRoutineCount++] = PiProcessNotifyRoutine[i]; - } - } RemoveEntryList(&Process->ProcessListEntry); KeReleaseSpinLock(&PsProcessListLock, oldIrql); - for (i = 0;i < NotifyRoutineCount; i++) - { - /* must be called below DISPATCH_LVL */ - NotifyRoutine[i](Process->InheritedFromUniqueProcessId, - (HANDLE)Process->UniqueProcessId, - FALSE); - } - /* KDB hook */ KDB_DELETEPROCESS_HOOK(Process); @@ -586,9 +564,6 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, PEPORT ExceptionPort; PVOID BaseAddress; PMEMORY_AREA MemoryArea; - ULONG i; - PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT]; - ULONG NotifyRoutineCount; DPRINT("NtCreateProcess(ObjectAttributes %x)\n",ObjectAttributes); @@ -696,26 +671,10 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, } KeAcquireSpinLock(&PsProcessListLock, &oldIrql); - NotifyRoutineCount = 0; - for (i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; i++) - { - if (PiProcessNotifyRoutine[i]) - { - NotifyRoutine[NotifyRoutineCount++] = PiProcessNotifyRoutine[i]; - } - } InsertHeadList(&PsProcessListHead, &Process->ProcessListEntry); InitializeListHead(&Process->ThreadListHead); KeReleaseSpinLock(&PsProcessListLock, oldIrql); - for (i = 0;i < NotifyRoutineCount; i++) - { - //must be called below DISPATCH_LVL - NotifyRoutine[i](Process->InheritedFromUniqueProcessId, - (HANDLE)Process->UniqueProcessId, - TRUE); - } - Process->Pcb.State = PROCESS_STATE_ACTIVE; /* @@ -1581,6 +1540,22 @@ PsLookupProcessByProcessId(IN PVOID ProcessId, return(STATUS_INVALID_PARAMETER); } +VOID +STDCALL +PspRunCreateProcessNotifyRoutines +( + PEPROCESS CurrentProcess, + BOOLEAN Create +) +{ + ULONG i; + HANDLE ProcessId = (HANDLE)CurrentProcess->UniqueProcessId; + HANDLE ParentId = CurrentProcess->InheritedFromUniqueProcessId; + + for(i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; ++ i) + if(PiProcessNotifyRoutine[i]) + PiProcessNotifyRoutine[i](ParentId, ProcessId, Create); +} /* * @implemented @@ -1589,11 +1564,8 @@ NTSTATUS STDCALL PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, IN BOOLEAN Remove) { - KIRQL oldIrql; ULONG i; - KeAcquireSpinLock(&PsProcessListLock, &oldIrql); - if (Remove) { for(i=0;i