mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
patch by Skywing: made existing eventpair code more efficient and added support for associating eventpairs with
threads and signaling them that way svn path=/trunk/; revision=6031
This commit is contained in:
parent
05023f216e
commit
413af2c984
14 changed files with 397 additions and 12 deletions
|
@ -14,7 +14,7 @@ lineclip linetest lock lpc messagebox mktime mstest multiwin \
|
|||
mutex nptest patblt pipe primitives pteb regtest sectest sertest \
|
||||
shaptest shm statst statst2 stretchblt suspend tcpsvr terminate \
|
||||
txtscale thread thread_msg tokentest vmtest winhello wm_erasebkgnd \
|
||||
wm_paint
|
||||
wm_paint eventpair threadwait
|
||||
|
||||
TEST_MISC =
|
||||
|
||||
|
|
65
reactos/apps/tests/eventpair/eventpair.c
Normal file
65
reactos/apps/tests/eventpair/eventpair.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Author: Skywing (skywing@valhallalegends.com)
|
||||
* Date: 09/09/2003
|
||||
* Purpose: Test Thread-EventPair functionality.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#ifndef NTAPI
|
||||
#define NTAPI WINAPI
|
||||
#endif
|
||||
|
||||
HANDLE MakeEventPair()
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE EventPair;
|
||||
OBJECT_ATTRIBUTES Attributes;
|
||||
|
||||
InitializeObjectAttributes(&Attributes, NULL, 0, NULL, NULL);
|
||||
Status = NtCreateEventPair(&EventPair, STANDARD_RIGHTS_ALL, &Attributes);
|
||||
printf("Status %08x creating eventpair\n", Status);
|
||||
return EventPair;
|
||||
}
|
||||
|
||||
DWORD __stdcall threadfunc(void* eventpair)
|
||||
{
|
||||
printf("Thread: Set eventpair status %08x\n", NtSetInformationThread(NtCurrentThread(), ThreadEventPair, &eventpair, sizeof(HANDLE)));
|
||||
Sleep(2500);
|
||||
|
||||
printf("Thread: Setting low and waiting high...\n");
|
||||
printf("Thread: status = %08x\n", NtSetLowWaitHighThread());
|
||||
printf("Thread: status = %08x\n", NtSetHighWaitLowThread());
|
||||
printf("Thread: Terminating...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
DWORD id;
|
||||
HANDLE EventPair, Thread;
|
||||
|
||||
printf("Main: NtSetLowWaitHighThread is at %08x\n", NtSetLowWaitHighThread);
|
||||
|
||||
EventPair = MakeEventPair();
|
||||
|
||||
if(!EventPair) {
|
||||
printf("Main: Could not create event pair.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Main: EventPair = %08x\n", EventPair);
|
||||
Thread = CreateThread(0, 0, threadfunc, EventPair, 0, &id);
|
||||
printf("Main: ThreadId for new thread is %08x\n", id);
|
||||
printf("Main: Setting high and waiting low\n");
|
||||
printf("Main: status = %08x\n", NtSetHighWaitLowEventPair(EventPair));
|
||||
Sleep(2500);
|
||||
printf("Main: status = %08x\n", NtSetLowWaitHighEventPair(EventPair));
|
||||
NtClose(EventPair);
|
||||
/* WaitForSingleObject(Thread, INFINITE); FIXME: Waiting on thread handle causes double spinlock acquisition (and subsequent crash) in PsUnblockThread - ntoskrnl/ps/thread.c */
|
||||
NtClose(Thread);
|
||||
printf("Main: Terminating...\n");
|
||||
return 0;
|
||||
}
|
21
reactos/apps/tests/eventpair/makefile
Normal file
21
reactos/apps/tests/eventpair/makefile
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: makefile,v 1.1 2003/09/10 06:12:21 vizzini Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_NORC = yes
|
||||
|
||||
TARGET_TYPE = program
|
||||
|
||||
TARGET_APPTYPE = console
|
||||
|
||||
TARGET_NAME = eventpair
|
||||
|
||||
TARGET_SDKLIBS = ntdll.a
|
||||
|
||||
TARGET_OBJECTS = $(TARGET_NAME).o
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
||||
# EOF
|
21
reactos/apps/tests/threadwait/makefile
Normal file
21
reactos/apps/tests/threadwait/makefile
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: makefile,v 1.1 2003/09/10 06:12:21 vizzini Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_NORC = yes
|
||||
|
||||
TARGET_TYPE = program
|
||||
|
||||
TARGET_APPTYPE = console
|
||||
|
||||
TARGET_NAME = threadwait
|
||||
|
||||
TARGET_SDKLIBS = ntdll.a
|
||||
|
||||
TARGET_OBJECTS = $(TARGET_NAME).o
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
||||
# EOF
|
31
reactos/apps/tests/threadwait/threadwait.c
Normal file
31
reactos/apps/tests/threadwait/threadwait.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Author: Skywing (skywing@valhallalegends.com)
|
||||
* Date: 09/09/2003
|
||||
* Purpose: Probe for PsUnblockThread crash due to double-acquire spin lock.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
DWORD __stdcall threadfunc(void* UNREFERENCED)
|
||||
{
|
||||
printf("Thread: Initialized\n");
|
||||
Sleep(2500);
|
||||
printf("Thread: Terminating...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
DWORD id;
|
||||
HANDLE Thread;
|
||||
|
||||
Thread = CreateThread(0, 0, threadfunc, 0, 0, &id);
|
||||
printf("Main: ThreadId for new thread is %08x\n", id);
|
||||
printf("Main: Waiting on thread...\n");
|
||||
WaitForSingleObject(Thread, INFINITE);
|
||||
printf("Main: OK, somebody fixed the PsUnblockThread spinlock double-acquire crash\n");
|
||||
NtClose(Thread);
|
||||
printf("Main: Terminating...\n");
|
||||
return 0;
|
||||
}
|
|
@ -159,6 +159,7 @@ NtSetEaFile ZwSetEaFile 16
|
|||
NtSetEvent ZwSetEvent 8
|
||||
NtSetHighEventPair ZwSetHighEventPair 4
|
||||
NtSetHighWaitLowEventPair ZwSetHighWaitLowEventPair 4
|
||||
NtSetHighWaitLowThread ZwSetHighWaitLowThread 0
|
||||
NtSetInformationFile ZwSetInformationFile 20
|
||||
NtSetInformationKey ZwSetInformationKey 16
|
||||
NtSetInformationObject ZwSetInformationObject 16
|
||||
|
@ -169,6 +170,7 @@ NtSetIntervalProfile ZwSetIntervalProfile 8
|
|||
NtSetLdtEntries ZwSetLdtEntries 24
|
||||
NtSetLowEventPair ZwSetLowEventPair 4
|
||||
NtSetLowWaitHighEventPair ZwSetLowWaitHighEventPair 4
|
||||
NtSetLowWaitHighThread ZwSetLowWaitHighThread 0
|
||||
NtSetSecurityObject ZwSetSecurityObject 12
|
||||
NtSetSystemEnvironmentValue ZwSetSystemEnvironmentValue 8
|
||||
NtSetSystemInformation ZwSetSystemInformation 12
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
/* $Id: zw.h,v 1.16 2003/09/03 20:14:22 ekohl Exp $
|
||||
/* $Id: zw.h,v 1.17 2003/09/10 06:12:21 vizzini Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -12,6 +12,7 @@
|
|||
* 04/08/98: Added some documentation (Ariadne)
|
||||
* 14/08/98: Added type TIME and change variable type from [1] to [0]
|
||||
* 14/09/98: Added for each Nt call a corresponding Zw Call
|
||||
* 09/08/03: Added ThreadEventPair routines
|
||||
*/
|
||||
|
||||
#ifndef __DDK_ZW_H
|
||||
|
@ -3469,6 +3470,41 @@ ZwSetLowWaitHighEventPair(
|
|||
HANDLE EventPair
|
||||
);
|
||||
|
||||
/* NtSetLowWaitHighThread effectively invokes NtSetLowWaitHighEventPair on the
|
||||
* event pair of the thread.
|
||||
*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtSetLowWaitHighThread(
|
||||
VOID
|
||||
);
|
||||
/* ZwSetLowWaitHighThread effectively invokes ZwSetLowWaitHighEventPair on the
|
||||
* event pair of the thread.
|
||||
*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
ZwSetLowWaitHighThread(
|
||||
VOID
|
||||
);
|
||||
|
||||
/* NtSetHighWaitLowThread effectively invokes NtSetHighWaitLowEventPair on the
|
||||
* event pair of the thread.
|
||||
*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtSetHighWaitLowThread(
|
||||
VOID
|
||||
);
|
||||
|
||||
/* ZwSetHighWaitLowThread effectively invokes ZwSetHighWaitLowEventPair on the
|
||||
* event pair of the thread.
|
||||
*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
ZwSetHighWaitLowThread(
|
||||
VOID
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtSetSecurityObject(
|
||||
|
|
|
@ -130,6 +130,8 @@ cp apps/tests/nptest/npclient.exe $ROS_INSTALL_TESTS
|
|||
cp apps/tests/atomtest/atomtest.exe $ROS_INSTALL_TESTS
|
||||
cp apps/tests/mutex/mutex.exe $ROS_INSTALL/bin
|
||||
cp apps/tests/winhello/winhello.exe $ROS_INSTALL/bin
|
||||
cp apps/tests/eventpair/eventpair.exe $ROS_INSTALL_TESTS
|
||||
cp apps/tests/threadwait/threadwait.exe $ROS_INSTALL_TESTS
|
||||
cp apps/tests/multiwin/multiwin.exe $ROS_INSTALL/bin
|
||||
cp apps/tests/wm_paint/wm_paint.exe $ROS_INSTALL_TESTS
|
||||
cp apps/tests/bitblt/lena.bmp $ROS_INSTALL_TESTS
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntdll.def,v 1.109 2003/09/08 09:56:56 weiden Exp $
|
||||
; $Id: ntdll.def,v 1.110 2003/09/10 06:12:21 vizzini Exp $
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
|
@ -222,6 +222,7 @@ NtSetEaFile@16
|
|||
NtSetEvent@8
|
||||
NtSetHighEventPair@4
|
||||
NtSetHighWaitLowEventPair@4
|
||||
NtSetHighWaitLowThread@0
|
||||
NtSetInformationFile@20
|
||||
NtSetInformationKey@16
|
||||
NtSetInformationObject@16
|
||||
|
@ -233,6 +234,7 @@ NtSetIoCompletion@20
|
|||
NtSetLdtEntries@24
|
||||
NtSetLowEventPair@4
|
||||
NtSetLowWaitHighEventPair@4
|
||||
NtSetLowWaitHighThread@0
|
||||
NtSetSecurityObject@12
|
||||
NtSetSystemEnvironmentValue@8
|
||||
NtSetSystemInformation@12
|
||||
|
@ -776,6 +778,7 @@ ZwSetEaFile@16
|
|||
ZwSetEvent@8
|
||||
ZwSetHighEventPair@4
|
||||
ZwSetHighWaitLowEventPair@4
|
||||
ZwSetHighWaitLowThread@0
|
||||
ZwSetInformationFile@20
|
||||
ZwSetInformationKey@16
|
||||
ZwSetInformationObject@16
|
||||
|
@ -787,6 +790,7 @@ ZwSetIoCompletion@20
|
|||
ZwSetLdtEntries@24
|
||||
ZwSetLowEventPair@4
|
||||
ZwSetLowWaitHighEventPair@4
|
||||
ZwSetLowWaitHighThread@0
|
||||
ZwSetSecurityObject@12
|
||||
ZwSetSystemEnvironmentValue@8
|
||||
ZwSetSystemInformation@12
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntdll.edf,v 1.99 2003/09/08 09:56:57 weiden Exp $
|
||||
; $Id: ntdll.edf,v 1.100 2003/09/10 06:12:21 vizzini Exp $
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
|
@ -222,6 +222,7 @@ NtSetEaFile=NtSetEaFile@16
|
|||
NtSetEvent=NtSetEvent@8
|
||||
NtSetHighEventPair=NtSetHighEventPair@4
|
||||
NtSetHighWaitLowEventPair=NtSetHighWaitLowEventPair@4
|
||||
NtSetHighWaitLowThread=NtSetHighWaitLowThread@0
|
||||
NtSetInformationFile=NtSetInformationFile@20
|
||||
NtSetInformationKey=NtSetInformationKey@16
|
||||
NtSetInformationObject=NtSetInformationObject@16
|
||||
|
@ -233,6 +234,7 @@ NtSetIoCompletion=NtSetIoCompletion@20
|
|||
NtSetLdtEntries=NtSetLdtEntries@24
|
||||
NtSetLowEventPair=NtSetLowEventPair@4
|
||||
NtSetLowWaitHighEventPair=NtSetLowWaitHighEventPair@4
|
||||
NtSetLowWaitHighThread=NtSetLowWaitHighThread@0
|
||||
NtSetSecurityObject=NtSetSecurityObject@12
|
||||
NtSetSystemEnvironmentValue=NtSetSystemEnvironmentValue@8
|
||||
NtSetSystemInformation=NtSetSystemInformation@12
|
||||
|
@ -776,6 +778,7 @@ ZwSetEaFile=ZwSetEaFile@16
|
|||
ZwSetEvent=ZwSetEvent@8
|
||||
ZwSetHighEventPair=ZwSetHighEventPair@4
|
||||
ZwSetHighWaitLowEventPair=ZwSetHighWaitLowEventPair@4
|
||||
ZwSetHighWaitLowThread=ZwSetHighWaitLowThread@0
|
||||
ZwSetInformationFile=ZwSetInformationFile@20
|
||||
ZwSetInformationKey=ZwSetInformationKey@16
|
||||
ZwSetInformationObject=ZwSetInformationObject@16
|
||||
|
@ -787,6 +790,7 @@ ZwSetIoCompletion=ZwSetIoCompletion@20
|
|||
ZwSetLdtEntries=ZwSetLdtEntries@24
|
||||
ZwSetLowEventPair=ZwSetLowEventPair@4
|
||||
ZwSetLowWaitHighEventPair=ZwSetLowWaitHighEventPair@4
|
||||
ZwSetLowWaitHighThread=ZwSetLowWaitHighThread@0
|
||||
ZwSetSecurityObject=ZwSetSecurityObject@12
|
||||
ZwSetSystemEnvironmentValue=ZwSetSystemEnvironmentValue@8
|
||||
ZwSetSystemInformation=ZwSetSystemInformation@12
|
||||
|
|
|
@ -90,6 +90,8 @@ typedef VOID (*PLOOKASIDE_MINMAX_ROUTINE)(
|
|||
/* GLOBAL VARIABLES *********************************************************/
|
||||
|
||||
TIME_ZONE_INFORMATION SystemTimeZoneInfo;
|
||||
extern POBJECT_TYPE ExEventPairObjectType;
|
||||
|
||||
|
||||
/* INITIALIZATION FUNCTIONS *************************************************/
|
||||
|
||||
|
@ -105,4 +107,13 @@ ExInitializeWorkerThreads(VOID);
|
|||
VOID
|
||||
ExpInitLookasideLists(VOID);
|
||||
|
||||
/* OTHER FUNCTIONS **********************************************************/
|
||||
|
||||
VOID
|
||||
ExpSwapThreadEventPair(
|
||||
IN struct _ETHREAD* Thread,
|
||||
IN struct _KEVENT_PAIR* EventPair
|
||||
);
|
||||
|
||||
|
||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_EXECUTIVE_H */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: evtpair.c,v 1.14 2003/06/07 12:23:14 chorns Exp $
|
||||
/* $Id: evtpair.c,v 1.15 2003/09/10 06:12:21 vizzini Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -7,6 +7,10 @@
|
|||
* 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 *****************************************************************/
|
||||
|
@ -14,11 +18,20 @@
|
|||
#define NTOS_MODE_KERNEL
|
||||
#include <ntos.h>
|
||||
#include <ntos/synch.h>
|
||||
#include <internal/ps.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#ifndef NTSYSAPI
|
||||
#define NTSYSAPI
|
||||
#endif
|
||||
|
||||
#ifndef NTAPI
|
||||
#define NTAPI STDCALL
|
||||
#endif
|
||||
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
|
@ -30,6 +43,8 @@ static GENERIC_MAPPING ExEventPairMapping = {
|
|||
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
||||
EVENT_PAIR_ALL_ACCESS};
|
||||
|
||||
static KSPIN_LOCK ExThreadEventPairSpinLock;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
@ -72,6 +87,8 @@ VOID NtInitializeEventPairImplementation(VOID)
|
|||
ExEventPairObjectType->OkayToClose = NULL;
|
||||
ExEventPairObjectType->Create = NtpCreateEventPair;
|
||||
ExEventPairObjectType->DuplicationNotify = NULL;
|
||||
|
||||
KeInitializeSpinLock(&ExThreadEventPairSpinLock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -172,7 +189,7 @@ NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
|
|||
|
||||
KeSetEvent(&EventPair->HighEvent,
|
||||
EVENT_INCREMENT,
|
||||
FALSE);
|
||||
TRUE);
|
||||
|
||||
KeWaitForSingleObject(&EventPair->LowEvent,
|
||||
WrEventPair,
|
||||
|
@ -205,7 +222,7 @@ NtSetLowEventPair(IN HANDLE EventPairHandle)
|
|||
|
||||
KeSetEvent(&EventPair->LowEvent,
|
||||
EVENT_INCREMENT,
|
||||
FALSE);
|
||||
TRUE);
|
||||
|
||||
ObDereferenceObject(EventPair);
|
||||
return(STATUS_SUCCESS);
|
||||
|
@ -232,7 +249,7 @@ NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
|
|||
|
||||
KeSetEvent(&EventPair->LowEvent,
|
||||
EVENT_INCREMENT,
|
||||
FALSE);
|
||||
TRUE);
|
||||
|
||||
KeWaitForSingleObject(&EventPair->HighEvent,
|
||||
WrEventPair,
|
||||
|
@ -302,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 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: create.c,v 1.64 2003/07/21 21:53:53 royce Exp $
|
||||
/* $Id: create.c,v 1.65 2003/09/10 06:12:22 vizzini Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -8,6 +8,7 @@
|
|||
* REVISION HISTORY:
|
||||
* 23/06/98: Created
|
||||
* 12/10/99: Phillip Susi: Thread priorities, and APC work
|
||||
* 09/08/03: Skywing: ThreadEventPair support (delete)
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -25,6 +26,7 @@
|
|||
#include <internal/ke.h>
|
||||
#include <internal/ob.h>
|
||||
#include <internal/ps.h>
|
||||
#include <internal/ex.h>
|
||||
#include <internal/se.h>
|
||||
#include <internal/id.h>
|
||||
#include <internal/dbg.h>
|
||||
|
@ -310,6 +312,7 @@ PiDeleteThread(PVOID ObjectBody)
|
|||
PiNrThreads--;
|
||||
RemoveEntryList(&Thread->Tcb.ThreadListEntry);
|
||||
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
|
||||
ExpSwapThreadEventPair(Thread, NULL); /* Release the associated eventpair object, if there was one */
|
||||
|
||||
for (i = 0; i < NotifyRoutineCount; i++)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: tinfo.c,v 1.21 2003/07/11 01:23:15 royce Exp $
|
||||
/* $Id: tinfo.c,v 1.22 2003/09/10 06:12:22 vizzini Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -7,12 +7,15 @@
|
|||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
* Updated 09/08/2003 by Skywing (skywing@valhallalegends.com)
|
||||
* to suppport thread-eventpairs.
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ps.h>
|
||||
#include <internal/ex.h>
|
||||
#include <internal/safe.h>
|
||||
|
||||
#include <internal/debug.h>
|
||||
|
@ -106,8 +109,38 @@ NtSetInformationThread(HANDLE ThreadHandle,
|
|||
break;
|
||||
|
||||
case ThreadEventPair:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
{
|
||||
PKEVENT_PAIR EventPair;
|
||||
|
||||
if (ThreadInformationLength != sizeof(HANDLE))
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ExGetPreviousMode() == UserMode) /* FIXME: Validate this for all infoclasses and system services */
|
||||
{
|
||||
DPRINT("NtSetInformationThread:ThreadEventPair: Checking user pointer %08x...\n", ThreadInformation);
|
||||
ProbeForRead(ThreadInformation, sizeof(HANDLE), sizeof(HANDLE)); /* FIXME: This entire function should be
|
||||
* wrapped in an SEH frame... return (NTSTATUS)GetExceptionCode() on exception */
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByHandle(*(PHANDLE)ThreadInformation,
|
||||
STANDARD_RIGHTS_ALL,
|
||||
ExEventPairObjectType,
|
||||
ExGetPreviousMode(),
|
||||
(PVOID*)&EventPair,
|
||||
NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ExpSwapThreadEventPair(Thread, EventPair); /* Note that the extra reference is kept intentionally */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case ThreadQuerySetWin32StartAddress:
|
||||
if (ThreadInformationLength != sizeof(ULONG))
|
||||
|
|
Loading…
Reference in a new issue