mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
173 lines
7.3 KiB
Diff
173 lines
7.3 KiB
Diff
From 94c6132d79ee02079fc952e33cccf0d1f456a1ec Mon Sep 17 00:00:00 2001
|
|
From: Zebediah Figura <z.figura12@gmail.com>
|
|
Date: Mon, 31 Aug 2020 23:00:16 -0500
|
|
Subject: [PATCH] ntdll: Implement NtAlertThreadByThreadId() and
|
|
NtWaitForAlertByThreadId().
|
|
|
|
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
|
---
|
|
dlls/ntdll/ntdll.spec | 2 ++
|
|
dlls/ntdll/unix/sync.c | 45 ++++++++++++++++++++++++++++++++++
|
|
dlls/ntdll/unix/thread.c | 2 ++
|
|
dlls/ntdll/unix/unix_private.h | 3 +++
|
|
dlls/ntdll/unix/virtual.c | 5 ++--
|
|
include/winternl.h | 2 ++
|
|
6 files changed, 57 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
|
|
index ac7365a84b6..91959e19149 100644
|
|
--- a/dlls/ntdll/ntdll.spec
|
|
+++ b/dlls/ntdll/ntdll.spec
|
|
@@ -137,6 +137,7 @@
|
|
@ stdcall -syscall NtAdjustPrivilegesToken(long long ptr long ptr ptr)
|
|
@ stdcall -syscall NtAlertResumeThread(long ptr)
|
|
@ stdcall -syscall NtAlertThread(long)
|
|
+@ stdcall -syscall NtAlertThreadByThreadId(ptr)
|
|
@ stdcall -syscall NtAllocateLocallyUniqueId(ptr)
|
|
# @ stub NtAllocateUserPhysicalPages
|
|
@ stdcall -syscall NtAllocateUuids(ptr ptr ptr ptr)
|
|
@@ -423,6 +424,7 @@
|
|
@ stub NtVdmControl
|
|
@ stub NtW32Call
|
|
@ stdcall -syscall NtWaitForDebugEvent(long long ptr ptr)
|
|
+@ stdcall -syscall NtWaitForAlertByThreadId(ptr ptr)
|
|
@ stdcall -syscall NtWaitForKeyedEvent(long ptr long ptr)
|
|
@ stdcall -syscall NtWaitForMultipleObjects(long ptr long long ptr)
|
|
@ stub NtWaitForProcessMutant
|
|
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
|
index 16635ee42fa..7e19fab1e97 100644
|
|
--- a/dlls/ntdll/unix/sync.c
|
|
+++ b/dlls/ntdll/unix/sync.c
|
|
@@ -81,6 +81,12 @@ static const LARGE_INTEGER zero_timeout;
|
|
|
|
static pthread_mutex_t addr_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
+static const char *debugstr_timeout( const LARGE_INTEGER *timeout )
|
|
+{
|
|
+ if (!timeout) return "(infinite)";
|
|
+ return wine_dbgstr_longlong( timeout->QuadPart );
|
|
+}
|
|
+
|
|
/* return a monotonic time counter, in Win32 ticks */
|
|
static inline ULONGLONG monotonic_counter(void)
|
|
{
|
|
@@ -2277,6 +2283,45 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
|
|
}
|
|
|
|
|
|
+/***********************************************************************
|
|
+ * NtAlertThreadByThreadId (NTDLL.@)
|
|
+ */
|
|
+NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
|
+{
|
|
+ struct ntdll_thread_data *thread_data;
|
|
+
|
|
+ TRACE( "%p\n", tid );
|
|
+
|
|
+ pthread_rwlock_rdlock( &teb_list_lock );
|
|
+
|
|
+ LIST_FOR_EACH_ENTRY( thread_data, &teb_list, struct ntdll_thread_data, entry )
|
|
+ {
|
|
+ TEB *teb = CONTAINING_RECORD( thread_data, TEB, GdiTebBatch );
|
|
+
|
|
+ if (teb->ClientId.UniqueThread == tid)
|
|
+ {
|
|
+ pthread_rwlock_unlock( &teb_list_lock );
|
|
+ NtSetEvent( thread_data->tid_alert_event, NULL );
|
|
+ return STATUS_SUCCESS;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pthread_rwlock_unlock( &teb_list_lock );
|
|
+ return STATUS_INVALID_CID;
|
|
+}
|
|
+
|
|
+
|
|
+/***********************************************************************
|
|
+ * NtWaitForAlertByThreadId (NTDLL.@)
|
|
+ */
|
|
+NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout )
|
|
+{
|
|
+ TRACE( "%p %s\n", address, debugstr_timeout( timeout ) );
|
|
+
|
|
+ return NtWaitForSingleObject( ntdll_get_thread_data()->tid_alert_event, FALSE, timeout );
|
|
+}
|
|
+
|
|
+
|
|
#ifdef __linux__
|
|
|
|
NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
|
|
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
|
|
index 00d29ae706b..87f5a97131e 100644
|
|
--- a/dlls/ntdll/unix/thread.c
|
|
+++ b/dlls/ntdll/unix/thread.c
|
|
@@ -252,6 +252,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
|
|
thread_data->start = start;
|
|
thread_data->param = param;
|
|
|
|
+ NtCreateEvent( &thread_data->tid_alert_event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE );
|
|
+
|
|
pthread_attr_init( &pthread_attr );
|
|
pthread_attr_setstack( &pthread_attr, teb->DeallocationStack,
|
|
(char *)teb->Tib.StackBase + extra_stack - (char *)teb->DeallocationStack );
|
|
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
|
index b8b6619c0a9..ae178fadd8b 100644
|
|
--- a/dlls/ntdll/unix/unix_private.h
|
|
+++ b/dlls/ntdll/unix/unix_private.h
|
|
@@ -58,6 +58,7 @@ struct ntdll_thread_data
|
|
struct list entry; /* entry in TEB list */
|
|
PRTL_THREAD_START_ROUTINE start; /* thread entry point */
|
|
void *param; /* thread entry point parameter */
|
|
+ HANDLE tid_alert_event; /* event for thread-id alerts */
|
|
};
|
|
|
|
C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) );
|
|
@@ -105,6 +106,8 @@ extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
|
|
extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
|
CONTEXT *context ) DECLSPEC_HIDDEN;
|
|
|
|
+extern struct list teb_list DECLSPEC_HIDDEN;
|
|
+extern pthread_rwlock_t teb_list_lock DECLSPEC_HIDDEN;
|
|
extern const char *home_dir DECLSPEC_HIDDEN;
|
|
extern const char *data_dir DECLSPEC_HIDDEN;
|
|
extern const char *build_dir DECLSPEC_HIDDEN;
|
|
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
|
index d1d00b91345..3e3c9b5f00e 100644
|
|
--- a/dlls/ntdll/unix/virtual.c
|
|
+++ b/dlls/ntdll/unix/virtual.c
|
|
@@ -162,8 +162,9 @@ struct _KUSER_SHARED_DATA *user_shared_data = (void *)0x7ffe0000;
|
|
static void *teb_block;
|
|
static void **next_free_teb;
|
|
static int teb_block_pos;
|
|
-static struct list teb_list = LIST_INIT( teb_list );
|
|
-static pthread_rwlock_t teb_list_lock = PTHREAD_RWLOCK_INITIALIZER;
|
|
+
|
|
+struct list teb_list = LIST_INIT( teb_list );
|
|
+pthread_rwlock_t teb_list_lock = PTHREAD_RWLOCK_INITIALIZER;
|
|
|
|
#define ROUND_ADDR(addr,mask) ((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
|
|
#define ROUND_SIZE(addr,size) (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask)
|
|
diff --git a/include/winternl.h b/include/winternl.h
|
|
index f0ab223ef2e..9a5a1b541b7 100644
|
|
--- a/include/winternl.h
|
|
+++ b/include/winternl.h
|
|
@@ -3229,6 +3229,7 @@ NTSYSAPI NTSTATUS WINAPI NtAdjustGroupsToken(HANDLE,BOOLEAN,PTOKEN_GROUPS,ULONG
|
|
NTSYSAPI NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
|
|
NTSYSAPI NTSTATUS WINAPI NtAlertResumeThread(HANDLE,PULONG);
|
|
NTSYSAPI NTSTATUS WINAPI NtAlertThread(HANDLE ThreadHandle);
|
|
+NTSYSAPI NTSTATUS WINAPI NtAlertThreadByThreadId(HANDLE);
|
|
NTSYSAPI NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID lpLuid);
|
|
NTSYSAPI NTSTATUS WINAPI NtAllocateUuids(PULARGE_INTEGER,PULONG,PULONG,PUCHAR);
|
|
NTSYSAPI NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,ULONG_PTR,SIZE_T*,ULONG,ULONG);
|
|
@@ -3467,6 +3468,7 @@ NTSYSAPI NTSTATUS WINAPI NtUnlockVirtualMemory(HANDLE,PVOID*,SIZE_T*,ULONG);
|
|
NTSYSAPI NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID);
|
|
NTSYSAPI NTSTATUS WINAPI NtVdmControl(ULONG,PVOID);
|
|
NTSYSAPI NTSTATUS WINAPI NtWaitForDebugEvent(HANDLE,BOOLEAN,LARGE_INTEGER*,DBGUI_WAIT_STATE_CHANGE*);
|
|
+NTSYSAPI NTSTATUS WINAPI NtWaitForAlertByThreadId(const void*,const LARGE_INTEGER*);
|
|
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE,const void*,BOOLEAN,const LARGE_INTEGER*);
|
|
NTSYSAPI NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,const LARGE_INTEGER*);
|
|
NTSYSAPI NTSTATUS WINAPI NtWaitForMultipleObjects(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*);
|
|
--
|
|
2.20.1
|
|
|