mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
2002-08-09 David Welch <welch@computer2.darkstar.org>
* ntoskrnl/ps/create.c (NtCreateThread): Call PsSuspendThread if NtCreateThread has CreateSuspended as TRUE. * ntoskrnl/ps/suspend.c (PsSuspendThread, PsResumeThread, PiSuspendThreadKernelRoutine): Fixed suspend functionality. 2002-08-09 David Welch <welch@computer2.darkstar.org> * ntoskrnl/ke/i386/usertrap.c (print_user_address): Copy the LDR variable from the right address. 2002-08-09 David Welch <welch@computer2.darkstar.org> * ntoskrnl/ke/apc.c (KiDeliverNormalApc): Check for kernel APCs pending on exit from the kernel. * ntoskrnl/ke/apc.c (KiDeliverNormalApc, KiDeliverUserApc, KiDeliverApc): Set the APC's inserted flag to FALSE after removing it from the thread's queue. 2002-08-09 David Welch <welch@computer2.darkstar.org> * lib/kernel32/thread/thread.c (ThreadStartup): Don't call DLL entrypoints; this is done by LdrInitializeThunk. * lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call DLLs in initialization order; take the loader lock before calling. 2002-08-09 David Welch <welch@computer2.darkstar.org> * apps/tests/thread/thread.c (main): Test suspend and resume functionality. svn path=/trunk/; revision=3324
This commit is contained in:
parent
5a801d58c3
commit
95fbecfd46
12 changed files with 165 additions and 126 deletions
|
@ -1,3 +1,36 @@
|
||||||
|
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/ps/create.c (NtCreateThread): Call PsSuspendThread
|
||||||
|
if NtCreateThread has CreateSuspended as TRUE.
|
||||||
|
* ntoskrnl/ps/suspend.c (PsSuspendThread, PsResumeThread,
|
||||||
|
PiSuspendThreadKernelRoutine): Fixed suspend functionality.
|
||||||
|
|
||||||
|
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/ke/i386/usertrap.c (print_user_address): Copy
|
||||||
|
the LDR variable from the right address.
|
||||||
|
|
||||||
|
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* ntoskrnl/ke/apc.c (KiDeliverNormalApc): Check for
|
||||||
|
kernel APCs pending on exit from the kernel.
|
||||||
|
* ntoskrnl/ke/apc.c (KiDeliverNormalApc, KiDeliverUserApc,
|
||||||
|
KiDeliverApc): Set the APC's inserted flag to FALSE after
|
||||||
|
removing it from the thread's queue.
|
||||||
|
|
||||||
|
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* lib/kernel32/thread/thread.c (ThreadStartup): Don't
|
||||||
|
call DLL entrypoints; this is done by LdrInitializeThunk.
|
||||||
|
* lib/ntdll/ldr/startup.c (LdrInitializeThunk): Call
|
||||||
|
DLLs in initialization order; take the loader lock before
|
||||||
|
calling.
|
||||||
|
|
||||||
|
2002-08-09 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
|
* apps/tests/thread/thread.c (main): Test suspend and
|
||||||
|
resume functionality.
|
||||||
|
|
||||||
2002-08-08 David Welch <welch@computer2.darkstar.org>
|
2002-08-08 David Welch <welch@computer2.darkstar.org>
|
||||||
|
|
||||||
* ntoskrnl/mm/section (NtQuerySection): Return the
|
* ntoskrnl/mm/section (NtQuerySection): Return the
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: thread.c,v 1.7 2001/02/06 00:11:17 dwelch Exp $
|
/* $Id: thread.c,v 1.8 2002/08/09 17:23:56 dwelch Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -44,7 +44,7 @@ int main (int argc, char* argv[])
|
||||||
DWORD i=0;
|
DWORD i=0;
|
||||||
DWORD id;
|
DWORD id;
|
||||||
ULONG nr;
|
ULONG nr;
|
||||||
|
HANDLE ThreadHandle[NR_THREADS];
|
||||||
|
|
||||||
// The user must supply one argument (the seed). if he/she doesn't
|
// The user must supply one argument (the seed). if he/she doesn't
|
||||||
// then we show the help.
|
// then we show the help.
|
||||||
|
@ -60,16 +60,30 @@ int main (int argc, char* argv[])
|
||||||
printf("Creating %d threads...\n",NR_THREADS*2);
|
printf("Creating %d threads...\n",NR_THREADS*2);
|
||||||
for (i=0;i<NR_THREADS;i++)
|
for (i=0;i<NR_THREADS;i++)
|
||||||
{
|
{
|
||||||
CreateThread(NULL,
|
ThreadHandle[i] = CreateThread(NULL,
|
||||||
0,
|
0,
|
||||||
thread_main1,
|
thread_main1,
|
||||||
(LPVOID)i,
|
(LPVOID)i,
|
||||||
0,
|
CREATE_SUSPENDED,
|
||||||
&id);
|
&id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i=0;i<NR_THREADS;i++)
|
||||||
|
{
|
||||||
|
ResumeThread(ThreadHandle[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<NR_THREADS;i++)
|
||||||
|
{
|
||||||
|
SuspendThread(ThreadHandle[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<NR_THREADS;i++)
|
||||||
|
{
|
||||||
|
ResumeThread(ThreadHandle[i]);
|
||||||
|
}
|
||||||
|
|
||||||
printf("All threads created...\n");
|
printf("All threads created...\n");
|
||||||
for(;;);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: thread.c,v 1.26 2001/08/15 20:35:39 ea Exp $
|
/* $Id: thread.c,v 1.27 2002/08/09 17:23:56 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -26,16 +26,6 @@
|
||||||
|
|
||||||
static VOID ThreadAttachDlls (VOID);
|
static VOID ThreadAttachDlls (VOID);
|
||||||
|
|
||||||
/* Type for a DLL's entry point */
|
|
||||||
typedef
|
|
||||||
WINBOOL
|
|
||||||
STDCALL
|
|
||||||
(* PDLLMAIN_FUNC) (
|
|
||||||
HANDLE hInst,
|
|
||||||
ULONG ul_reason_for_call,
|
|
||||||
LPVOID lpReserved
|
|
||||||
);
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
static VOID STDCALL
|
static VOID STDCALL
|
||||||
|
@ -44,8 +34,6 @@ ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
{
|
{
|
||||||
UINT uExitCode;
|
UINT uExitCode;
|
||||||
|
|
||||||
ThreadAttachDlls ();
|
|
||||||
|
|
||||||
/* FIXME: notify csrss of thread creation ?? */
|
/* FIXME: notify csrss of thread creation ?? */
|
||||||
|
|
||||||
uExitCode = (lpStartAddress)(lpParameter);
|
uExitCode = (lpStartAddress)(lpParameter);
|
||||||
|
@ -53,42 +41,6 @@ ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
ExitThread(uExitCode);
|
ExitThread(uExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
|
||||||
ThreadAttachDlls (VOID)
|
|
||||||
{
|
|
||||||
PLIST_ENTRY ModuleListHead;
|
|
||||||
PLIST_ENTRY Entry;
|
|
||||||
PLDR_MODULE Module;
|
|
||||||
|
|
||||||
DPRINT("ThreadAttachDlls() called\n");
|
|
||||||
|
|
||||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
|
||||||
|
|
||||||
ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
|
|
||||||
Entry = ModuleListHead->Blink;
|
|
||||||
|
|
||||||
while (Entry != ModuleListHead)
|
|
||||||
{
|
|
||||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
|
|
||||||
|
|
||||||
if (Module->EntryPoint != 0)
|
|
||||||
{
|
|
||||||
PDLLMAIN_FUNC Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint;
|
|
||||||
|
|
||||||
DPRINT("Calling entry point at 0x%08x\n", Entrypoint);
|
|
||||||
Entrypoint (Module->BaseAddress,
|
|
||||||
DLL_THREAD_ATTACH,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Entry = Entry->Blink;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
|
||||||
|
|
||||||
DPRINT("ThreadAttachDlls() done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
DWORD dwStackSize,
|
DWORD dwStackSize,
|
||||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: startup.c,v 1.39 2002/08/08 17:54:13 dwelch Exp $
|
/* $Id: startup.c,v 1.40 2002/08/09 17:23:56 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -62,11 +62,14 @@ LdrInitializeThunk (ULONG Unknown1,
|
||||||
PDLLMAIN_FUNC Entrypoint;
|
PDLLMAIN_FUNC Entrypoint;
|
||||||
PLDR_MODULE current;
|
PLDR_MODULE current;
|
||||||
|
|
||||||
current_entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
|
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||||
while (current_entry != &NtCurrentPeb()->Ldr->InLoadOrderModuleList)
|
current_entry =
|
||||||
|
NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Flink;
|
||||||
|
while (current_entry !=
|
||||||
|
&NtCurrentPeb()->Ldr->InInitializationOrderModuleList)
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, LDR_MODULE,
|
current = CONTAINING_RECORD(current_entry, LDR_MODULE,
|
||||||
InLoadOrderModuleList);
|
InInitializationOrderModuleList);
|
||||||
Entrypoint = (PDLLMAIN_FUNC)current->EntryPoint;
|
Entrypoint = (PDLLMAIN_FUNC)current->EntryPoint;
|
||||||
if (Entrypoint != NULL &&
|
if (Entrypoint != NULL &&
|
||||||
current->BaseAddress != NtCurrentPeb()->ImageBaseAddress)
|
current->BaseAddress != NtCurrentPeb()->ImageBaseAddress)
|
||||||
|
@ -75,6 +78,7 @@ LdrInitializeThunk (ULONG Unknown1,
|
||||||
}
|
}
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
|
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: ps.h,v 1.37 2002/08/08 17:54:14 dwelch Exp $
|
/* $Id: ps.h,v 1.38 2002/08/09 17:23:56 dwelch Exp $
|
||||||
*
|
*
|
||||||
* FILE: ntoskrnl/ke/kthread.c
|
* FILE: ntoskrnl/ke/kthread.c
|
||||||
* PURPOSE: Process manager definitions
|
* PURPOSE: Process manager definitions
|
||||||
|
@ -580,6 +580,8 @@ PiTimeoutThread(struct _KDPC *dpc,
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
PsDispatchThread(ULONG NewThreadStatus);
|
PsDispatchThread(ULONG NewThreadStatus);
|
||||||
|
VOID
|
||||||
|
PsInitialiseSuspendImplementation(VOID);
|
||||||
|
|
||||||
#endif /* ASSEMBLER */
|
#endif /* ASSEMBLER */
|
||||||
|
|
||||||
|
|
|
@ -90,32 +90,35 @@ KiDeliverNormalApc(VOID)
|
||||||
|
|
||||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||||
while(!IsListEmpty(&(Thread->Tcb.ApcState.ApcListHead[0])))
|
while(!IsListEmpty(&(Thread->Tcb.ApcState.ApcListHead[0])))
|
||||||
{
|
{
|
||||||
current = Thread->Tcb.ApcState.ApcListHead[0].Blink;
|
current = Thread->Tcb.ApcState.ApcListHead[0].Blink;
|
||||||
Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
|
Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
|
||||||
if (Apc->NormalRoutine != NULL)
|
if (Apc->NormalRoutine == NULL)
|
||||||
{
|
{
|
||||||
(VOID)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]);
|
DbgPrint("Exiting kernel with kernel APCs pending.\n");
|
||||||
Thread->Tcb.ApcState.KernelApcInProgress++;
|
KeBugCheck(0);
|
||||||
Thread->Tcb.ApcState.KernelApcPending--;
|
}
|
||||||
|
(VOID)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]);
|
||||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
Apc->Inserted = FALSE;
|
||||||
|
Thread->Tcb.ApcState.KernelApcInProgress++;
|
||||||
NormalRoutine = Apc->NormalRoutine;
|
Thread->Tcb.ApcState.KernelApcPending--;
|
||||||
NormalContext = Apc->NormalContext;
|
|
||||||
SystemArgument1 = Apc->SystemArgument1;
|
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||||
SystemArgument2 = Apc->SystemArgument2;
|
|
||||||
Apc->KernelRoutine(Apc,
|
NormalRoutine = Apc->NormalRoutine;
|
||||||
&NormalRoutine,
|
NormalContext = Apc->NormalContext;
|
||||||
&NormalContext,
|
SystemArgument1 = Apc->SystemArgument1;
|
||||||
&SystemArgument1,
|
SystemArgument2 = Apc->SystemArgument2;
|
||||||
&SystemArgument2);
|
Apc->KernelRoutine(Apc,
|
||||||
NormalRoutine(NormalContext, SystemArgument1, SystemArgument2);
|
&NormalRoutine,
|
||||||
|
&NormalContext,
|
||||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
&SystemArgument1,
|
||||||
Thread->Tcb.ApcState.KernelApcInProgress--;
|
&SystemArgument2);
|
||||||
}
|
NormalRoutine(NormalContext, SystemArgument1, SystemArgument2);
|
||||||
}
|
|
||||||
|
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||||
|
Thread->Tcb.ApcState.KernelApcInProgress--;
|
||||||
|
}
|
||||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +164,9 @@ KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
|
||||||
while (!IsListEmpty(&Thread->ApcState.ApcListHead[1]))
|
while (!IsListEmpty(&Thread->ApcState.ApcListHead[1]))
|
||||||
{
|
{
|
||||||
current_entry = RemoveHeadList(&Thread->ApcState.ApcListHead[1]);
|
current_entry = RemoveHeadList(&Thread->ApcState.ApcListHead[1]);
|
||||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
|
||||||
Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry);
|
Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry);
|
||||||
|
Apc->Inserted = FALSE;
|
||||||
|
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save the thread's current context (in other words the registers
|
* Save the thread's current context (in other words the registers
|
||||||
|
@ -259,6 +263,7 @@ KiDeliverApc(ULONG Unknown1,
|
||||||
if (Apc->NormalRoutine == NULL)
|
if (Apc->NormalRoutine == NULL)
|
||||||
{
|
{
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
|
Apc->Inserted = FALSE;
|
||||||
RemoveEntryList(&Apc->ApcListEntry);
|
RemoveEntryList(&Apc->ApcListEntry);
|
||||||
Thread->Tcb.ApcState.KernelApcInProgress++;
|
Thread->Tcb.ApcState.KernelApcInProgress++;
|
||||||
Thread->Tcb.ApcState.KernelApcPending--;
|
Thread->Tcb.ApcState.KernelApcPending--;
|
||||||
|
|
|
@ -92,7 +92,7 @@ print_user_address(PVOID address)
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = MmSafeCopyFromUser(&Ldr, Peb->Ldr, sizeof(PPEB_LDR_DATA));
|
Status = MmSafeCopyFromUser(&Ldr, &Peb->Ldr, sizeof(PPEB_LDR_DATA));
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("<%x>", address);
|
DbgPrint("<%x>", address);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: kthread.c,v 1.30 2002/08/08 17:54:14 dwelch Exp $
|
/* $Id: kthread.c,v 1.31 2002/08/09 17:23:57 dwelch Exp $
|
||||||
*
|
*
|
||||||
* FILE: ntoskrnl/ke/kthread.c
|
* FILE: ntoskrnl/ke/kthread.c
|
||||||
* PURPOSE: Microkernel thread support
|
* PURPOSE: Microkernel thread support
|
||||||
|
@ -224,7 +224,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
PiSuspendThreadNormalRoutine,
|
PiSuspendThreadNormalRoutine,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
NULL);
|
NULL);
|
||||||
KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 255);
|
KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
|
||||||
Thread->ThreadListEntry.Flink = NULL;
|
Thread->ThreadListEntry.Flink = NULL;
|
||||||
Thread->ThreadListEntry.Blink = NULL;
|
Thread->ThreadListEntry.Blink = NULL;
|
||||||
Thread->FreezeCount = 0;
|
Thread->FreezeCount = 0;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: sem.c,v 1.8 2001/03/16 23:04:59 dwelch Exp $
|
/* $Id: sem.c,v 1.9 2002/08/09 17:23:57 dwelch Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/sem.c
|
* FILE: ntoskrnl/ke/sem.c
|
||||||
|
@ -81,30 +81,28 @@ KeReleaseSemaphore (PKSEMAPHORE Semaphore,
|
||||||
* object is Not-Signaled.
|
* object is Not-Signaled.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG initState = Semaphore->Header.SignalState;
|
ULONG InitialState;
|
||||||
|
|
||||||
DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
|
DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
|
||||||
"Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
|
"Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
|
||||||
|
|
||||||
KeAcquireDispatcherDatabaseLock(Wait);
|
KeAcquireDispatcherDatabaseLock(Wait);
|
||||||
|
|
||||||
if (Semaphore->Limit < initState+Adjustment
|
InitialState = Semaphore->Header.SignalState;
|
||||||
|| initState > initState+Adjustment)
|
if (Semaphore->Limit < InitialState + Adjustment ||
|
||||||
|
InitialState > InitialState + Adjustment)
|
||||||
{
|
{
|
||||||
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
|
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Semaphore->Header.SignalState+=Adjustment;
|
Semaphore->Header.SignalState += Adjustment;
|
||||||
DPRINT("initState %d\n", initState);
|
if (InitialState == 0)
|
||||||
if(initState == 0)
|
|
||||||
{
|
{
|
||||||
// wake up SignalState waiters
|
KeDispatcherObjectWake(&Semaphore->Header);
|
||||||
DPRINT("Waking waiters\n");
|
|
||||||
KeDispatcherObjectWake(&Semaphore->Header);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseDispatcherDatabaseLock(Wait);
|
KeReleaseDispatcherDatabaseLock(Wait);
|
||||||
return initState;
|
return(InitialState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: create.c,v 1.48 2002/08/08 17:54:16 dwelch Exp $
|
/* $Id: create.c,v 1.49 2002/08/09 17:23:57 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -590,15 +590,13 @@ NtCreateThread(PHANDLE ThreadHandle,
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attention: TebBase is in user memory space */
|
|
||||||
Thread->Tcb.Teb = TebBase;
|
Thread->Tcb.Teb = TebBase;
|
||||||
|
|
||||||
Thread->StartAddress=NULL;
|
Thread->StartAddress = NULL;
|
||||||
|
|
||||||
if (Client != NULL)
|
if (Client != NULL)
|
||||||
{
|
{
|
||||||
*Client=Thread->Cid;
|
*Client = Thread->Cid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -615,6 +613,10 @@ NtCreateThread(PHANDLE ThreadHandle,
|
||||||
* If the thread is to be created suspended then queue an APC to
|
* If the thread is to be created suspended then queue an APC to
|
||||||
* do the suspend before we run any userspace code.
|
* do the suspend before we run any userspace code.
|
||||||
*/
|
*/
|
||||||
|
if (CreateSuspended)
|
||||||
|
{
|
||||||
|
PsSuspendThread(Thread, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Queue an APC to the thread that will execute the ntdll startup
|
* Queue an APC to the thread that will execute the ntdll startup
|
||||||
|
@ -680,7 +682,7 @@ PsCreateSystemThread(PHANDLE ThreadHandle,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread->StartAddress=StartRoutine;
|
Thread->StartAddress = StartRoutine;
|
||||||
Status = Ke386InitThread(&Thread->Tcb,
|
Status = Ke386InitThread(&Thread->Tcb,
|
||||||
StartRoutine,
|
StartRoutine,
|
||||||
StartContext);
|
StartContext);
|
||||||
|
@ -689,7 +691,7 @@ PsCreateSystemThread(PHANDLE ThreadHandle,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClientId!=NULL)
|
if (ClientId != NULL)
|
||||||
{
|
{
|
||||||
*ClientId=Thread->Cid;
|
*ClientId=Thread->Cid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: psmgr.c,v 1.11 2001/07/12 17:21:06 ekohl Exp $
|
/* $Id: psmgr.c,v 1.12 2002/08/09 17:23:57 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -32,6 +32,7 @@ VOID PiInitProcessManager(VOID)
|
||||||
PsInitThreadManagment();
|
PsInitThreadManagment();
|
||||||
PsInitIdleThread();
|
PsInitIdleThread();
|
||||||
PiInitApcManagement();
|
PiInitApcManagement();
|
||||||
|
PsInitialiseSuspendImplementation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: suspend.c,v 1.7 2002/07/10 15:17:35 ekohl Exp $
|
/* $Id: suspend.c,v 1.8 2002/08/09 17:23:57 dwelch Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ps/suspend.c
|
* FILE: ntoskrnl/ps/suspend.c
|
||||||
|
@ -39,6 +39,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
static FAST_MUTEX SuspendMutex;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
|
@ -62,20 +66,36 @@ PiSuspendThreadNormalRoutine(PVOID NormalContext,
|
||||||
PVOID SystemArgument1,
|
PVOID SystemArgument1,
|
||||||
PVOID SystemArgument2)
|
PVOID SystemArgument2)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&PsGetCurrentThread()->Tcb.SuspendSemaphore,
|
PETHREAD CurrentThread = PsGetCurrentThread();
|
||||||
0,
|
while (CurrentThread->Tcb.SuspendCount > 0)
|
||||||
UserMode,
|
{
|
||||||
TRUE,
|
KeWaitForSingleObject(&CurrentThread->Tcb.SuspendSemaphore,
|
||||||
NULL);
|
0,
|
||||||
|
UserMode,
|
||||||
|
TRUE,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PsResumeThread(PETHREAD Thread, PULONG SuspendCount)
|
PsResumeThread(PETHREAD Thread, PULONG SuspendCount)
|
||||||
{
|
{
|
||||||
*SuspendCount = InterlockedDecrement((PULONG)&Thread->Tcb.SuspendCount);
|
ExAcquireFastMutex(&SuspendMutex);
|
||||||
KeReleaseSemaphore(&Thread->Tcb.SuspendSemaphore, IO_NO_INCREMENT, 1, FALSE);
|
if (SuspendCount != NULL)
|
||||||
|
{
|
||||||
|
*SuspendCount = Thread->Tcb.SuspendCount;
|
||||||
|
}
|
||||||
|
if (Thread->Tcb.SuspendCount > 0)
|
||||||
|
{
|
||||||
|
Thread->Tcb.SuspendCount--;
|
||||||
|
if (Thread->Tcb.SuspendCount == 0)
|
||||||
|
{
|
||||||
|
KeReleaseSemaphore(&Thread->Tcb.SuspendSemaphore, IO_NO_INCREMENT,
|
||||||
|
1, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExReleaseFastMutex(&SuspendMutex);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,19 +105,21 @@ PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
|
||||||
{
|
{
|
||||||
ULONG OldValue;
|
ULONG OldValue;
|
||||||
|
|
||||||
OldValue = InterlockedIncrement((PULONG)&Thread->Tcb.SuspendCount);
|
ExAcquireFastMutex(&SuspendMutex);
|
||||||
if (OldValue == 0)
|
OldValue = Thread->Tcb.SuspendCount;
|
||||||
|
Thread->Tcb.SuspendCount++;
|
||||||
|
if (!Thread->Tcb.SuspendApc.Inserted)
|
||||||
{
|
{
|
||||||
KeInsertQueueApc(&Thread->Tcb.SuspendApc,
|
KeInsertQueueApc(&Thread->Tcb.SuspendApc,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
else
|
ExReleaseFastMutex(&SuspendMutex);
|
||||||
|
if (PreviousSuspendCount != NULL)
|
||||||
{
|
{
|
||||||
InterlockedDecrement(&Thread->Tcb.SuspendSemaphore.Header.SignalState);
|
*PreviousSuspendCount = OldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,4 +208,10 @@ NtSuspendThread(IN HANDLE ThreadHandle,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PsInitialiseSuspendImplementation(VOID)
|
||||||
|
{
|
||||||
|
ExInitializeFastMutex(&SuspendMutex);
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue