mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 05:52:57 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
290
ntoskrnl/ke/eventobj.c
Normal file
290
ntoskrnl/ke/eventobj.c
Normal file
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ke/eventobj.c
|
||||
* PURPOSE: Implements the Event Dispatcher Object
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeClearEvent(IN PKEVENT Event)
|
||||
{
|
||||
ASSERT_EVENT(Event);
|
||||
|
||||
/* Reset Signal State */
|
||||
Event->Header.SignalState = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeInitializeEvent(OUT PKEVENT Event,
|
||||
IN EVENT_TYPE Type,
|
||||
IN BOOLEAN State)
|
||||
{
|
||||
/* Initialize the Dispatcher Header */
|
||||
Event->Header.Type = Type;
|
||||
//Event->Header.Signalling = FALSE; // fails in kmtest
|
||||
Event->Header.Size = sizeof(KEVENT) / sizeof(ULONG);
|
||||
Event->Header.SignalState = State;
|
||||
InitializeListHead(&(Event->Header.WaitListHead));
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeInitializeEventPair(IN PKEVENT_PAIR EventPair)
|
||||
{
|
||||
/* Initialize the Event Pair Type and Size */
|
||||
EventPair->Type = EventPairObject;
|
||||
EventPair->Size = sizeof(KEVENT_PAIR);
|
||||
|
||||
/* Initialize the two Events */
|
||||
KeInitializeEvent(&EventPair->LowEvent, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent(&EventPair->HighEvent, SynchronizationEvent, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
LONG
|
||||
NTAPI
|
||||
KePulseEvent(IN PKEVENT Event,
|
||||
IN KPRIORITY Increment,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
LONG PreviousState;
|
||||
PKTHREAD Thread;
|
||||
ASSERT_EVENT(Event);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
/* Lock the Dispatcher Database */
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Save the Old State */
|
||||
PreviousState = Event->Header.SignalState;
|
||||
|
||||
/* Check if we are non-signaled and we have stuff in the Wait Queue */
|
||||
if (!PreviousState && !IsListEmpty(&Event->Header.WaitListHead))
|
||||
{
|
||||
/* Set the Event to Signaled */
|
||||
Event->Header.SignalState = 1;
|
||||
|
||||
/* Wake the Event */
|
||||
KiWaitTest(&Event->Header, Increment);
|
||||
}
|
||||
|
||||
/* Unsignal it */
|
||||
Event->Header.SignalState = 0;
|
||||
|
||||
/* Check what wait state was requested */
|
||||
if (Wait == FALSE)
|
||||
{
|
||||
/* Wait not requested, release Dispatcher Database and return */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return Locked and with a Wait */
|
||||
Thread = KeGetCurrentThread();
|
||||
Thread->WaitNext = TRUE;
|
||||
Thread->WaitIrql = OldIrql;
|
||||
}
|
||||
|
||||
/* Return the previous State */
|
||||
return PreviousState;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
LONG
|
||||
NTAPI
|
||||
KeReadStateEvent(IN PKEVENT Event)
|
||||
{
|
||||
ASSERT_EVENT(Event);
|
||||
|
||||
/* Return the Signal State */
|
||||
return Event->Header.SignalState;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
LONG
|
||||
NTAPI
|
||||
KeResetEvent(IN PKEVENT Event)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
LONG PreviousState;
|
||||
ASSERT_EVENT(Event);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
/* Lock the Dispatcher Database */
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Save the Previous State */
|
||||
PreviousState = Event->Header.SignalState;
|
||||
|
||||
/* Set it to zero */
|
||||
Event->Header.SignalState = 0;
|
||||
|
||||
/* Release Dispatcher Database and return previous state */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
return PreviousState;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
LONG
|
||||
NTAPI
|
||||
KeSetEvent(IN PKEVENT Event,
|
||||
IN KPRIORITY Increment,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
LONG PreviousState;
|
||||
PKTHREAD Thread;
|
||||
ASSERT_EVENT(Event);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
/*
|
||||
* Check if this is an signaled notification event without an upcoming wait.
|
||||
* In this case, we can immediately return TRUE, without locking.
|
||||
*/
|
||||
if ((Event->Header.Type == EventNotificationObject) &&
|
||||
(Event->Header.SignalState == 1) &&
|
||||
!(Wait))
|
||||
{
|
||||
/* Return the signal state (TRUE/Signalled) */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Lock the Dispathcer Database */
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Save the Previous State */
|
||||
PreviousState = Event->Header.SignalState;
|
||||
|
||||
/* Set the Event to Signaled */
|
||||
Event->Header.SignalState = 1;
|
||||
|
||||
/* Check if the event just became signaled now, and it has waiters */
|
||||
if (!(PreviousState) && !(IsListEmpty(&Event->Header.WaitListHead)))
|
||||
{
|
||||
/* Check the type of event */
|
||||
if (Event->Header.Type == EventNotificationObject)
|
||||
{
|
||||
/* Unwait the thread */
|
||||
KxUnwaitThread(&Event->Header, Increment);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise unwait the thread and unsignal the event */
|
||||
KxUnwaitThreadForEvent(Event, Increment);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check what wait state was requested */
|
||||
if (!Wait)
|
||||
{
|
||||
/* Wait not requested, release Dispatcher Database and return */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return Locked and with a Wait */
|
||||
Thread = KeGetCurrentThread();
|
||||
Thread->WaitNext = TRUE;
|
||||
Thread->WaitIrql = OldIrql;
|
||||
}
|
||||
|
||||
/* Return the previous State */
|
||||
return PreviousState;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeSetEventBoostPriority(IN PKEVENT Event,
|
||||
IN PKTHREAD *WaitingThread OPTIONAL)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PKWAIT_BLOCK WaitBlock;
|
||||
PKTHREAD Thread = KeGetCurrentThread(), WaitThread;
|
||||
ASSERT(Event->Header.Type == EventSynchronizationObject);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
/* Acquire Dispatcher Database Lock */
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Check if the list is empty */
|
||||
if (IsListEmpty(&Event->Header.WaitListHead))
|
||||
{
|
||||
/* Set the Event to Signaled */
|
||||
Event->Header.SignalState = 1;
|
||||
|
||||
/* Return */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the Wait Block */
|
||||
WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
|
||||
KWAIT_BLOCK,
|
||||
WaitListEntry);
|
||||
|
||||
/* Check if this is a WaitAll */
|
||||
if (WaitBlock->WaitType == WaitAll)
|
||||
{
|
||||
/* Set the Event to Signaled */
|
||||
Event->Header.SignalState = 1;
|
||||
|
||||
/* Unwait the thread and unsignal the event */
|
||||
KxUnwaitThreadForEvent(Event, EVENT_INCREMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return waiting thread to caller */
|
||||
WaitThread = WaitBlock->Thread;
|
||||
if (WaitingThread) *WaitingThread = WaitThread;
|
||||
|
||||
/* Calculate new priority */
|
||||
Thread->Priority = KiComputeNewPriority(Thread, 0);
|
||||
|
||||
/* Unlink the waiting thread */
|
||||
KiUnlinkThread(WaitThread, STATUS_SUCCESS);
|
||||
|
||||
/* Request priority boosting */
|
||||
WaitThread->AdjustIncrement = Thread->Priority;
|
||||
WaitThread->AdjustReason = AdjustBoost;
|
||||
|
||||
/* Ready the thread */
|
||||
KiReadyThread(WaitThread);
|
||||
}
|
||||
|
||||
/* Release the Dispatcher Database Lock */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue