X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fnt%2Fevtpair.c;fp=ntoskrnl%2Fnt%2Fevtpair.c;h=04c02fd7928c7bcbd03753276e97a1e81663b3d6;hp=d320bfb91ec2a2a462743140065bddb1fed9c461;hb=7c0cf90e3b750f1f0dc83b2eec9e5c68a512c30f;hpb=ee8b63255465d8c28be3e7bd11628015708fc1ab diff --git a/ntoskrnl/nt/evtpair.c b/ntoskrnl/nt/evtpair.c index d320bfb..04c02fd 100644 --- a/ntoskrnl/nt/evtpair.c +++ b/ntoskrnl/nt/evtpair.c @@ -7,17 +7,31 @@ * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: * Created 22/05/98 + * Updated 09/08/2003 by Skywing (skywing@valhallalegends.com) + * to correctly maintain ownership of the dispatcher lock + * between KeSetEvent and KeWaitForSingleObject calls. + * Additionally, implemented the thread-eventpair routines. */ /* INCLUDES *****************************************************************/ -#include +#define NTOS_MODE_KERNEL +#include #include +#include #include #define NDEBUG #include +#ifndef NTSYSAPI +#define NTSYSAPI +#endif + +#ifndef NTAPI +#define NTAPI STDCALL +#endif + /* GLOBALS *******************************************************************/ @@ -29,6 +43,8 @@ static GENERIC_MAPPING ExEventPairMapping = { STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, EVENT_PAIR_ALL_ACCESS}; +static KSPIN_LOCK ExThreadEventPairSpinLock; + /* FUNCTIONS *****************************************************************/ NTSTATUS STDCALL @@ -71,6 +87,8 @@ VOID NtInitializeEventPairImplementation(VOID) ExEventPairObjectType->OkayToClose = NULL; ExEventPairObjectType->Create = NtpCreateEventPair; ExEventPairObjectType->DuplicationNotify = NULL; + + KeInitializeSpinLock(&ExThreadEventPairSpinLock); } @@ -83,7 +101,7 @@ NtCreateEventPair(OUT PHANDLE EventPairHandle, NTSTATUS Status; DPRINT("NtCreateEventPair()\n"); - Status = ObCreateObject(EventPairHandle, + Status = ObRosCreateObject(EventPairHandle, DesiredAccess, ObjectAttributes, ExEventPairObjectType, @@ -171,7 +189,7 @@ NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle) KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, - FALSE); + TRUE); KeWaitForSingleObject(&EventPair->LowEvent, WrEventPair, @@ -231,7 +249,7 @@ NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle) KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, - FALSE); + TRUE); KeWaitForSingleObject(&EventPair->HighEvent, WrEventPair, @@ -301,4 +319,139 @@ NtWaitHighEventPair(IN HANDLE EventPairHandle) return(STATUS_SUCCESS); } +/* + * Author: Skywing (skywing@valhallalegends.com), 09/08/2003 + * Note that the eventpair spinlock must be acquired when setting the thread + * eventpair via NtSetInformationThread. + * @implemented + */ +NTSYSAPI +NTSTATUS +NTAPI +NtSetLowWaitHighThread( + VOID + ) +{ + PETHREAD Thread; + PKEVENT_PAIR EventPair; + NTSTATUS Status; + KIRQL Irql; + + Thread = PsGetCurrentThread(); + + if(!Thread->EventPair) + return STATUS_NO_EVENT_PAIR; + + KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql); + + EventPair = Thread->EventPair; + + if(EventPair) + ObReferenceObjectByPointer(EventPair, + EVENT_PAIR_ALL_ACCESS, + ExEventPairObjectType, + UserMode); + + KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql); + + if(EventPair == NULL) + return STATUS_NO_EVENT_PAIR; + + KeSetEvent(&EventPair->LowEvent, + EVENT_INCREMENT, + TRUE); + + Status = KeWaitForSingleObject(&EventPair->HighEvent, + WrEventPair, + UserMode, + FALSE, + NULL); + + ObDereferenceObject(EventPair); + + return Status; +} + + +/* + * Author: Skywing (skywing@valhallalegends.com), 09/08/2003 + * Note that the eventpair spinlock must be acquired when setting the thread + * eventpair via NtSetInformationThread. + * @implemented + */ +NTSYSAPI +NTSTATUS +NTAPI +NtSetHighWaitLowThread( + VOID + ) +{ + PETHREAD Thread; + PKEVENT_PAIR EventPair; + NTSTATUS Status; + KIRQL Irql; + + Thread = PsGetCurrentThread(); + + if(!Thread->EventPair) + return STATUS_NO_EVENT_PAIR; + + KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql); + + EventPair = PsGetCurrentThread()->EventPair; + + if(EventPair) + ObReferenceObjectByPointer(EventPair, + EVENT_PAIR_ALL_ACCESS, + ExEventPairObjectType, + UserMode); + + KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql); + + if(EventPair == NULL) + return STATUS_NO_EVENT_PAIR; + + KeSetEvent(&EventPair->HighEvent, + EVENT_INCREMENT, + TRUE); + + Status = KeWaitForSingleObject(&EventPair->LowEvent, + WrEventPair, + UserMode, + FALSE, + NULL); + + ObDereferenceObject(EventPair); + + return Status; +} + +/* + * Author: Skywing (skywing@valhallalegends.com), 09/08/2003 + * Note that the eventpair spinlock must be acquired when waiting on the + * eventpair via NtSetLow/HighWaitHigh/LowThread. Additionally, when + * deleting a thread object, NtpSwapThreadEventPair(Thread, NULL) should + * be called to release any preexisting eventpair object associated with + * the thread. The Microsoft name for this function is not known. + */ +VOID +ExpSwapThreadEventPair( + IN PETHREAD Thread, + IN PKEVENT_PAIR EventPair + ) +{ + PKEVENT_PAIR OriginalEventPair; + KIRQL Irql; + + KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql); + + OriginalEventPair = Thread->EventPair; + Thread->EventPair = EventPair; + + if(OriginalEventPair) + ObDereferenceObject(OriginalEventPair); + + KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql); +} + /* EOF */