mirror of
https://github.com/reactos/reactos.git
synced 2024-09-29 05:54:05 +00:00
Reimplemented dispatcher database lock and synchronization primitives.
This fixes bug #26. svn path=/trunk/; revision=6502
This commit is contained in:
parent
de4f0fd8ab
commit
df0af98c1b
|
@ -44,8 +44,11 @@ VOID STDCALL KeRescheduleThread();
|
|||
|
||||
VOID KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip);
|
||||
|
||||
VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait);
|
||||
VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait);
|
||||
KIRQL KeAcquireDispatcherDatabaseLock(VOID);
|
||||
VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
|
||||
VOID KeReleaseDispatcherDatabaseLock(KIRQL Irql);
|
||||
VOID KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
|
||||
|
||||
BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr);
|
||||
VOID STDCALL KeExpireTimers(PKDPC Apc,
|
||||
PVOID Arg1,
|
||||
|
@ -59,7 +62,6 @@ VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus, BOOL U
|
|||
PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
|
||||
VOID KeContextToTrapFrame(PCONTEXT Context,
|
||||
PKTRAP_FRAME TrapFrame);
|
||||
VOID KeReleaseDispatcherDatabaseLockAtDpcLevel(BOOLEAN Wait);
|
||||
VOID
|
||||
KiDeliverNormalApc(VOID);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <internal/ke.h>
|
||||
#include <internal/id.h>
|
||||
#include <internal/ps.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -80,14 +81,29 @@ LONG STDCALL KeSetEvent (PKEVENT Event,
|
|||
KPRIORITY Increment,
|
||||
BOOLEAN Wait)
|
||||
{
|
||||
int ret;
|
||||
KIRQL OldIrql;
|
||||
int ret;
|
||||
|
||||
DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
|
||||
KeAcquireDispatcherDatabaseLock(Wait);
|
||||
ret = InterlockedExchange(&(Event->Header.SignalState),1);
|
||||
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
|
||||
KeReleaseDispatcherDatabaseLock(Wait);
|
||||
return(ret);
|
||||
DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
|
||||
ret = InterlockedExchange(&(Event->Header.SignalState),1);
|
||||
|
||||
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
|
||||
|
||||
if (Wait == FALSE)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
KTHREAD *Thread = KeGetCurrentThread();
|
||||
Thread->WaitNext = Wait;
|
||||
Thread->WaitIrql = OldIrql;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -97,15 +113,27 @@ NTSTATUS STDCALL KePulseEvent (PKEVENT Event,
|
|||
KPRIORITY Increment,
|
||||
BOOLEAN Wait)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
int ret;
|
||||
|
||||
DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
|
||||
KeAcquireDispatcherDatabaseLock(Wait);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
ret = InterlockedExchange(&(Event->Header.SignalState),1);
|
||||
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
|
||||
InterlockedExchange(&(Event->Header.SignalState),0);
|
||||
KeReleaseDispatcherDatabaseLock(Wait);
|
||||
return((NTSTATUS)ret);
|
||||
|
||||
if (Wait == FALSE)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
KTHREAD *Thread = KeGetCurrentThread();
|
||||
Thread->WaitNext = Wait;
|
||||
Thread->WaitIrql = OldIrql;
|
||||
}
|
||||
|
||||
return ((NTSTATUS)ret);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -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: mutex.c,v 1.14 2003/07/21 21:53:51 royce Exp $
|
||||
/* $Id: mutex.c,v 1.15 2003/11/02 01:15:15 ekohl Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/mutex.c
|
||||
|
@ -71,7 +71,9 @@ LONG STDCALL
|
|||
KeReleaseMutex(IN PKMUTEX Mutex,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
KeAcquireDispatcherDatabaseLock(Wait);
|
||||
KIRQL OldIrql;
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
if (Mutex->OwnerThread != KeGetCurrentThread())
|
||||
{
|
||||
DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutex %p\n", Mutex);
|
||||
|
@ -86,7 +88,18 @@ KeReleaseMutex(IN PKMUTEX Mutex,
|
|||
RemoveEntryList(&Mutex->MutantListEntry);
|
||||
KeDispatcherObjectWake(&Mutex->Header);
|
||||
}
|
||||
KeReleaseDispatcherDatabaseLock(Wait);
|
||||
|
||||
if (Wait == FALSE)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
KTHREAD *Thread = KeGetCurrentThread();
|
||||
Thread->WaitNext = Wait;
|
||||
Thread->WaitIrql = OldIrql;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -153,7 +166,9 @@ KeReleaseMutant(IN PKMUTANT Mutant,
|
|||
IN BOOLEAN Abandon,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
KeAcquireDispatcherDatabaseLock(Wait);
|
||||
KIRQL OldIrql;
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
if (Abandon == FALSE)
|
||||
{
|
||||
if (Mutant->OwnerThread != NULL && Mutant->OwnerThread != KeGetCurrentThread())
|
||||
|
@ -183,7 +198,17 @@ KeReleaseMutant(IN PKMUTANT Mutant,
|
|||
KeDispatcherObjectWake(&Mutant->Header);
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(Wait);
|
||||
if (Wait == FALSE)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
KTHREAD *Thread = KeGetCurrentThread();
|
||||
Thread->WaitNext = Wait;
|
||||
Thread->WaitIrql = OldIrql;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -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: queue.c,v 1.9 2003/08/14 18:30:28 silverblade Exp $
|
||||
/* $Id: queue.c,v 1.10 2003/11/02 01:15:15 ekohl Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/queue.c
|
||||
|
@ -75,10 +75,11 @@ KiInsertQueue(
|
|||
)
|
||||
{
|
||||
ULONG InitialState;
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("KiInsertQueue(Queue %x, Entry %x)\n", Queue, Entry);
|
||||
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
|
||||
InitialState = Queue->Header.SignalState;
|
||||
Queue->Header.SignalState++;
|
||||
|
@ -97,7 +98,7 @@ KiInsertQueue(
|
|||
KeDispatcherObjectWake(&Queue->Header);
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
return InitialState;
|
||||
}
|
||||
|
||||
|
@ -136,8 +137,9 @@ KeRemoveQueue(IN PKQUEUE Queue,
|
|||
PLIST_ENTRY ListEntry;
|
||||
NTSTATUS Status;
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
KIRQL OldIrql;
|
||||
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
|
||||
//assiciate new thread with queue?
|
||||
if (Thread->Queue != Queue)
|
||||
|
@ -158,12 +160,12 @@ KeRemoveQueue(IN PKQUEUE Queue,
|
|||
{
|
||||
ListEntry = RemoveHeadList(&Queue->EntryListHead);
|
||||
Queue->Header.SignalState--;
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
return ListEntry;
|
||||
}
|
||||
|
||||
//need to wait for it...
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
|
||||
Status = KeWaitForSingleObject(Queue,
|
||||
WrQueue,
|
||||
|
@ -177,9 +179,9 @@ KeRemoveQueue(IN PKQUEUE Queue,
|
|||
}
|
||||
else
|
||||
{
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
ListEntry = RemoveHeadList(&Queue->EntryListHead);
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
return ListEntry;
|
||||
}
|
||||
|
||||
|
@ -194,12 +196,13 @@ KeRundownQueue(IN PKQUEUE Queue)
|
|||
{
|
||||
PLIST_ENTRY EnumEntry;
|
||||
PKTHREAD Thread;
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("KeRundownQueue(Queue %x)\n", Queue);
|
||||
|
||||
//FIXME: should we wake thread waiting on a queue?
|
||||
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
|
||||
// Clear Queue and QueueListEntry members of all threads associated with this queue
|
||||
while (!IsListEmpty(&Queue->ThreadListHead))
|
||||
|
@ -215,7 +218,7 @@ KeRundownQueue(IN PKQUEUE Queue)
|
|||
else
|
||||
EnumEntry = NULL;
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
|
||||
return EnumEntry;
|
||||
}
|
||||
|
|
|
@ -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: sem.c,v 1.13 2003/07/10 17:44:06 royce Exp $
|
||||
/* $Id: sem.c,v 1.14 2003/11/02 01:15:15 ekohl Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/sem.c
|
||||
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ke.h>
|
||||
#include <internal/ps.h>
|
||||
#include <internal/id.h>
|
||||
|
||||
#define NDEBUG
|
||||
|
@ -40,7 +41,7 @@
|
|||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
VOID STDCALL
|
||||
KeInitializeSemaphore (PKSEMAPHORE Semaphore,
|
||||
LONG Count,
|
||||
LONG Limit)
|
||||
|
@ -55,7 +56,7 @@ KeInitializeSemaphore (PKSEMAPHORE Semaphore,
|
|||
/*
|
||||
* @implemented
|
||||
*/
|
||||
LONG STDCALL
|
||||
LONG STDCALL
|
||||
KeReadStateSemaphore (PKSEMAPHORE Semaphore)
|
||||
{
|
||||
return(Semaphore->Header.SignalState);
|
||||
|
@ -64,7 +65,7 @@ KeReadStateSemaphore (PKSEMAPHORE Semaphore)
|
|||
/*
|
||||
* @implemented
|
||||
*/
|
||||
LONG STDCALL
|
||||
LONG STDCALL
|
||||
KeReleaseSemaphore (PKSEMAPHORE Semaphore,
|
||||
KPRIORITY Increment,
|
||||
LONG Adjustment,
|
||||
|
@ -90,27 +91,38 @@ KeReleaseSemaphore (PKSEMAPHORE Semaphore,
|
|||
* object is Not-Signaled.
|
||||
*/
|
||||
{
|
||||
ULONG InitialState;
|
||||
|
||||
DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
|
||||
ULONG InitialState;
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
|
||||
"Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
|
||||
|
||||
KeAcquireDispatcherDatabaseLock(Wait);
|
||||
|
||||
InitialState = Semaphore->Header.SignalState;
|
||||
if (Semaphore->Limit < (LONG) InitialState + Adjustment ||
|
||||
InitialState > InitialState + Adjustment)
|
||||
{
|
||||
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
|
||||
}
|
||||
|
||||
Semaphore->Header.SignalState += Adjustment;
|
||||
if (InitialState == 0)
|
||||
{
|
||||
KeDispatcherObjectWake(&Semaphore->Header);
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(Wait);
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
|
||||
InitialState = Semaphore->Header.SignalState;
|
||||
if (Semaphore->Limit < (LONG) InitialState + Adjustment ||
|
||||
InitialState > InitialState + Adjustment)
|
||||
{
|
||||
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
|
||||
}
|
||||
|
||||
Semaphore->Header.SignalState += Adjustment;
|
||||
if (InitialState == 0)
|
||||
{
|
||||
KeDispatcherObjectWake(&Semaphore->Header);
|
||||
}
|
||||
|
||||
if (Wait == FALSE)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
KTHREAD *Thread = KeGetCurrentThread();
|
||||
Thread->WaitNext = Wait;
|
||||
Thread->WaitIrql = OldIrql;
|
||||
}
|
||||
|
||||
return(InitialState);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: timer.c,v 1.62 2003/10/12 17:05:45 hbirr Exp $
|
||||
/* $Id: timer.c,v 1.63 2003/11/02 01:15:15 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -400,6 +400,8 @@ KeQueryTickCount(PLARGE_INTEGER TickCount)
|
|||
STATIC VOID
|
||||
HandleExpiredTimer(PKTIMER current)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("HandleExpiredTime(current %x)\n",current);
|
||||
if (current->Dpc != NULL)
|
||||
{
|
||||
|
@ -410,10 +412,10 @@ HandleExpiredTimer(PKTIMER current)
|
|||
NULL);
|
||||
DPRINT("Finished dpc routine\n");
|
||||
}
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
current->Header.SignalState = TRUE;
|
||||
KeDispatcherObjectWake(¤t->Header);
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
if (current->Period != 0)
|
||||
{
|
||||
current->DueTime.QuadPart +=
|
||||
|
|
|
@ -29,9 +29,6 @@
|
|||
/* GLOBALS ******************************************************************/
|
||||
|
||||
static KSPIN_LOCK DispatcherDatabaseLock;
|
||||
static BOOLEAN WaitSet = FALSE;
|
||||
static KIRQL oldlvl = PASSIVE_LEVEL;
|
||||
static PKTHREAD Owner = NULL;
|
||||
|
||||
#define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE)
|
||||
#define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE)
|
||||
|
@ -51,41 +48,52 @@ VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
|
|||
InitializeListHead(&(Header->WaitListHead));
|
||||
}
|
||||
|
||||
VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait)
|
||||
|
||||
KIRQL
|
||||
KeAcquireDispatcherDatabaseLock(VOID)
|
||||
/*
|
||||
* PURPOSE: Acquires the dispatcher database lock for the caller
|
||||
*/
|
||||
{
|
||||
DPRINT("KeAcquireDispatcherDatabaseLock(Wait %x)\n",Wait);
|
||||
if (WaitSet && Owner == KeGetCurrentThread())
|
||||
{
|
||||
return;
|
||||
}
|
||||
KeAcquireSpinLock(&DispatcherDatabaseLock, &oldlvl);
|
||||
WaitSet = Wait;
|
||||
Owner = KeGetCurrentThread();
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("KeAcquireDispatcherDatabaseLock()\n");
|
||||
|
||||
KeAcquireSpinLock (&DispatcherDatabaseLock, &OldIrql);
|
||||
return OldIrql;
|
||||
}
|
||||
|
||||
VOID KeReleaseDispatcherDatabaseLockAtDpcLevel(BOOLEAN Wait)
|
||||
|
||||
VOID
|
||||
KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID)
|
||||
/*
|
||||
* PURPOSE: Acquires the dispatcher database lock for the caller
|
||||
*/
|
||||
{
|
||||
DPRINT("KeReleaseDispatcherDatabaseLockAtDpcLevel(Wait %x) WaitSet=%x\n", Wait, WaitSet);
|
||||
if (Wait == WaitSet)
|
||||
{
|
||||
Owner = NULL;
|
||||
KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
|
||||
}
|
||||
DPRINT("KeAcquireDispatcherDatabaseLockAtDpcLevel()\n");
|
||||
|
||||
KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock);
|
||||
}
|
||||
|
||||
VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait)
|
||||
|
||||
VOID
|
||||
KeReleaseDispatcherDatabaseLock(KIRQL OldIrql)
|
||||
{
|
||||
DPRINT("KeReleaseDispatcherDatabaseLock(Wait %x) WaitSet=%x\n",Wait,WaitSet);
|
||||
if (Wait == WaitSet)
|
||||
{
|
||||
Owner = NULL;
|
||||
KeReleaseSpinLock(&DispatcherDatabaseLock, oldlvl);
|
||||
}
|
||||
DPRINT("KeReleaseDispatcherDatabaseLock(OldIrql %x)\n",OldIrql);
|
||||
|
||||
KeReleaseSpinLock(&DispatcherDatabaseLock, OldIrql);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID)
|
||||
{
|
||||
DPRINT("KeReleaseDispatcherDatabaseLock()\n");
|
||||
|
||||
KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
|
||||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
KiSideEffectsBeforeWake(DISPATCHER_HEADER * hdr,
|
||||
PKTHREAD Thread)
|
||||
|
@ -190,8 +198,9 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus, BOOL Unblock)
|
|||
{
|
||||
PKWAIT_BLOCK WaitBlock, PrevWaitBlock;
|
||||
BOOLEAN WasWaiting = FALSE;
|
||||
KIRQL OldIrql;
|
||||
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
|
||||
WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList;
|
||||
if (WaitBlock != NULL)
|
||||
|
@ -216,7 +225,7 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus, BOOL Unblock)
|
|||
PsUnblockThread(Thread, &WaitStatus);
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
|
@ -459,6 +468,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
KIRQL WaitIrql;
|
||||
KIRQL OldIrql;
|
||||
BOOLEAN Abandoned;
|
||||
|
||||
DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
|
||||
|
@ -499,7 +509,16 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
|
||||
do
|
||||
{
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
if (CurrentThread->WaitNext)
|
||||
{
|
||||
OldIrql = CurrentThread->WaitIrql;
|
||||
CurrentThread->WaitNext = 0;
|
||||
CurrentThread->WaitIrql = PASSIVE_LEVEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are going to wait alertably and a user apc is pending
|
||||
|
@ -507,7 +526,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
*/
|
||||
if (Alertable && KiTestAlert())
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
return (STATUS_USER_APC);
|
||||
}
|
||||
|
||||
|
@ -533,7 +552,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
KeCancelTimer(&CurrentThread->Timer);
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
||||
DPRINT("One object is (already) signaled!\n");
|
||||
if (Abandoned == TRUE)
|
||||
|
@ -560,7 +579,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
KeCancelTimer(&CurrentThread->Timer);
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
DPRINT("All objects are (already) signaled!\n");
|
||||
|
||||
if (Abandoned == TRUE)
|
||||
|
@ -574,7 +593,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
//zero timeout is used for testing if the object(s) can be immediately acquired
|
||||
if (Timeout != NULL && Timeout->QuadPart == 0)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
return STATUS_TIMEOUT;
|
||||
}
|
||||
|
||||
|
@ -585,7 +604,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
{
|
||||
KiSideEffectsBeforeWake(&CurrentThread->Timer.Header, CurrentThread);
|
||||
KeCancelTimer(&CurrentThread->Timer);
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
return (STATUS_TIMEOUT);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: kill.c,v 1.65 2003/09/18 17:55:21 fireball Exp $
|
||||
/* $Id: kill.c,v 1.66 2003/11/02 01:16:21 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -95,14 +95,14 @@ PsReapThreads(VOID)
|
|||
|
||||
if (current->Tcb.State == THREAD_STATE_TERMINATED_1)
|
||||
{
|
||||
PEPROCESS Process = current->ThreadsProcess;
|
||||
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);
|
||||
Last = IsListEmpty(&Process->ThreadListHead);
|
||||
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
|
||||
|
||||
if (Last)
|
||||
|
@ -113,14 +113,14 @@ PsReapThreads(VOID)
|
|||
{
|
||||
if (current->Tcb.Teb)
|
||||
{
|
||||
/* If this is not the last thread for the process than free the memory
|
||||
/* 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;
|
||||
PVOID DeallocationStack;
|
||||
HANDLE ProcessHandle;
|
||||
Status = ObCreateHandle(PsGetCurrentProcess(), Process, PROCESS_ALL_ACCESS, FALSE, &ProcessHandle);
|
||||
Status = ObCreateHandle(PsGetCurrentProcess(), Process, PROCESS_ALL_ACCESS, FALSE, &ProcessHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("ObCreateHandle failed, status = %x\n", Status);
|
||||
|
@ -128,14 +128,14 @@ PsReapThreads(VOID)
|
|||
}
|
||||
Offset = FIELD_OFFSET(TEB, DeallocationStack);
|
||||
Length = 0;
|
||||
NtReadVirtualMemory(ProcessHandle, (PVOID)current->Tcb.Teb + Offset,
|
||||
NtReadVirtualMemory(ProcessHandle, (PVOID)current->Tcb.Teb + Offset,
|
||||
(PVOID)&DeallocationStack, sizeof(PVOID), &Length);
|
||||
if (DeallocationStack && Length == sizeof(PVOID))
|
||||
{
|
||||
NtFreeVirtualMemory(ProcessHandle, &DeallocationStack, &Length, MEM_RELEASE);
|
||||
NtFreeVirtualMemory(ProcessHandle, &DeallocationStack, &Length, MEM_RELEASE);
|
||||
}
|
||||
Length = PAGE_SIZE;
|
||||
NtFreeVirtualMemory(ProcessHandle, (PVOID*)¤t->Tcb.Teb, &Length, MEM_RELEASE);
|
||||
NtFreeVirtualMemory(ProcessHandle, (PVOID*)¤t->Tcb.Teb, &Length, MEM_RELEASE);
|
||||
NtClose(ProcessHandle);
|
||||
}
|
||||
}
|
||||
|
@ -183,12 +183,12 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
|
|||
current_entry = Thread->MutantListHead.Flink;
|
||||
}
|
||||
|
||||
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
|
||||
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
|
||||
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
KeAcquireDispatcherDatabaseLockAtDpcLevel();
|
||||
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
|
||||
KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
|
||||
KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE);
|
||||
KeReleaseDispatcherDatabaseLockFromDpcLevel ();
|
||||
|
||||
ExpSwapThreadEventPair(CurrentThread, NULL); /* Release the associated eventpair object, if there was one */
|
||||
KeRemoveAllWaitsThread (CurrentThread, STATUS_UNSUCCESSFUL, FALSE);
|
||||
|
@ -263,6 +263,8 @@ NTSTATUS STDCALL
|
|||
PiTerminateProcess(PEPROCESS Process,
|
||||
NTSTATUS ExitStatus)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("PiTerminateProcess(Process %x, ExitStatus %x) PC %d HC %d\n",
|
||||
Process, ExitStatus, ObGetObjectPointerCount(Process),
|
||||
ObGetObjectHandleCount(Process));
|
||||
|
@ -278,10 +280,10 @@ PiTerminateProcess(PEPROCESS Process,
|
|||
KeAttachProcess( Process );
|
||||
ObCloseAllHandles(Process);
|
||||
KeDetachProcess();
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
Process->Pcb.DispatcherHeader.SignalState = TRUE;
|
||||
KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
ObDereferenceObject(Process);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: thread.c,v 1.120 2003/10/12 17:05:50 hbirr Exp $
|
||||
/* $Id: thread.c,v 1.121 2003/11/02 01:16:21 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -52,7 +52,7 @@ ULONG PiNrThreads = 0;
|
|||
ULONG PiNrReadyThreads = 0;
|
||||
static HANDLE PiReaperThreadHandle;
|
||||
static KEVENT PiReaperThreadEvent;
|
||||
static BOOL PiReaperThreadShouldTerminate = FALSE;
|
||||
static BOOLEAN PiReaperThreadShouldTerminate = FALSE;
|
||||
ULONG PiNrThreadsAwaitingReaping = 0;
|
||||
|
||||
static GENERIC_MAPPING PiThreadMapping = {THREAD_READ,
|
||||
|
@ -293,7 +293,7 @@ PsDispatchThread(ULONG NewThreadStatus)
|
|||
/*
|
||||
* Save wait IRQL
|
||||
*/
|
||||
((PIKPCR) KeGetCurrentKPCR())->CurrentThread->WaitIrql = oldIrql;
|
||||
((PIKPCR) KeGetCurrentKPCR())->CurrentThread->WaitIrql = oldIrql;
|
||||
PsDispatchThreadNoLock(NewThreadStatus);
|
||||
KeLowerIrql(oldIrql);
|
||||
}
|
||||
|
@ -304,16 +304,16 @@ PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus)
|
|||
KIRQL oldIrql;
|
||||
|
||||
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
|
||||
if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State ||
|
||||
if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State ||
|
||||
THREAD_STATE_TERMINATED_2 == Thread->Tcb.State)
|
||||
{
|
||||
DPRINT("Can't unblock thread %d because it's terminating\n",
|
||||
DPRINT("Can't unblock thread %d because it's terminating\n",
|
||||
Thread->Cid.UniqueThread);
|
||||
}
|
||||
else if (THREAD_STATE_READY == Thread->Tcb.State ||
|
||||
THREAD_STATE_RUNNING == Thread->Tcb.State)
|
||||
{
|
||||
DPRINT("Can't unblock thread %d because it's ready or running\n",
|
||||
DPRINT("Can't unblock thread %d because it's ready or running\n",
|
||||
Thread->Cid.UniqueThread);
|
||||
}
|
||||
else
|
||||
|
@ -329,7 +329,7 @@ PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus)
|
|||
}
|
||||
|
||||
VOID
|
||||
PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
|
||||
PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
|
||||
BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
@ -345,7 +345,7 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
|
|||
{
|
||||
if (!DispatcherLock)
|
||||
{
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
KeAcquireDispatcherDatabaseLockAtDpcLevel();
|
||||
}
|
||||
WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList;
|
||||
while (WaitBlock)
|
||||
|
@ -354,7 +354,7 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
|
|||
WaitBlock = WaitBlock->NextWaitBlock;
|
||||
}
|
||||
Thread->Tcb.WaitBlockList = NULL;
|
||||
KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE);
|
||||
KeReleaseDispatcherDatabaseLockFromDpcLevel();
|
||||
PsDispatchThreadNoLock (THREAD_STATE_READY);
|
||||
if (Status != NULL)
|
||||
{
|
||||
|
@ -365,7 +365,7 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
|
|||
{
|
||||
if (DispatcherLock)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE);
|
||||
KeReleaseDispatcherDatabaseLockFromDpcLevel();
|
||||
}
|
||||
Thread->Tcb.Alertable = Alertable;
|
||||
Thread->Tcb.WaitMode = WaitMode;
|
||||
|
@ -618,7 +618,7 @@ KeSetAffinityThread(PKTHREAD Thread,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NTSTATUS STDCALL
|
||||
NtAlertResumeThread(IN HANDLE ThreadHandle,
|
||||
OUT PULONG SuspendCount)
|
||||
{
|
||||
|
@ -626,7 +626,8 @@ NtAlertResumeThread(IN HANDLE ThreadHandle,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL NtAlertThread (IN HANDLE ThreadHandle)
|
||||
NTSTATUS STDCALL
|
||||
NtAlertThread (IN HANDLE ThreadHandle)
|
||||
{
|
||||
PETHREAD Thread;
|
||||
NTSTATUS Status;
|
||||
|
@ -655,7 +656,7 @@ NTSTATUS STDCALL NtAlertThread (IN HANDLE ThreadHandle)
|
|||
*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
NTSTATUS STDCALL
|
||||
NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
|
@ -711,13 +712,13 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
|||
DesiredAccess,
|
||||
FALSE,
|
||||
ThreadHandle);
|
||||
ObDereferenceObject(EThread);
|
||||
ObDereferenceObject(EThread);
|
||||
}
|
||||
}
|
||||
return(Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NTSTATUS STDCALL
|
||||
NtContinue(IN PCONTEXT Context,
|
||||
IN BOOLEAN TestAlert)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue