wine-staging/patches/ntdll-NtAlertThreadByThreadId/0007-ntdll-Implement-thread-id-alerts-on-top-of-Mach-sema.patch
Zebediah Figura f4cb879b3d ntdll-NtAlertThreadByThreadId: Include mach/mach.h in unix_private.h.
Thanks to Dean Greer for finding this one.
2021-03-05 21:24:30 -06:00

140 lines
4.4 KiB
Diff

From 002d5f21931d383a28be7aefdcb0a5299e51afb8 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Mon, 31 Aug 2020 23:03:34 -0500
Subject: [PATCH] ntdll: Implement thread-id alerts on top of Mach semaphores
on Mac.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntdll/unix/sync.c | 44 ++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/thread.c | 4 ++++
dlls/ntdll/unix/unix_private.h | 9 +++++++
3 files changed, 57 insertions(+)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index f4f87ba5642..7d6423083e1 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -2301,6 +2301,10 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
if (teb->ClientId.UniqueThread == tid)
{
pthread_rwlock_unlock( &teb_list_lock );
+#ifdef __APPLE__
+ semaphore_signal( thread_data->tid_alert_sem );
+ return STATUS_SUCCESS;
+#else
#ifdef __linux__
if (use_futexes())
{
@@ -2312,6 +2316,7 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
#endif
NtSetEvent( thread_data->tid_alert_event, NULL );
return STATUS_SUCCESS;
+#endif
}
}
@@ -2349,6 +2354,44 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
{
TRACE( "%p %s\n", address, debugstr_timeout( timeout ) );
+#ifdef __APPLE__
+ {
+ semaphore_t sem = ntdll_get_thread_data()->tid_alert_sem;
+ ULONGLONG end;
+ kern_return_t ret;
+
+ if (timeout)
+ {
+ if (timeout->QuadPart == TIMEOUT_INFINITE)
+ timeout = NULL;
+ else
+ end = get_absolute_timeout( timeout );
+ }
+
+ for (;;)
+ {
+ if (timeout)
+ {
+ LONGLONG timeleft = update_timeout( end );
+ mach_timespec_t timespec;
+
+ timespec.tv_sec = timeleft / (ULONGLONG)TICKSPERSEC;
+ timespec.tv_nsec = (timeleft % TICKSPERSEC) * 100;
+ ret = semaphore_timedwait( sem, timespec );
+ }
+ else
+ ret = semaphore_wait( sem );
+
+ switch (ret)
+ {
+ case KERN_SUCCESS: return STATUS_ALERTED;
+ case KERN_ABORTED: continue;
+ case KERN_OPERATION_TIMED_OUT: return STATUS_TIMEOUT;
+ default: return STATUS_INVALID_HANDLE;
+ }
+ }
+ }
+#else
#ifdef __linux__
if (use_futexes())
{
@@ -2384,6 +2427,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
}
#endif
return NtWaitForSingleObject( ntdll_get_thread_data()->tid_alert_event, FALSE, timeout );
+#endif
}
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index 87f5a97131e..e97a9657f03 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -252,7 +252,11 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
thread_data->start = start;
thread_data->param = param;
+#ifdef __APPLE__
+ semaphore_create( mach_task_self(), &thread_data->tid_alert_sem, SYNC_POLICY_FIFO, 0 );
+#else
NtCreateEvent( &thread_data->tid_alert_event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE );
+#endif
pthread_attr_init( &pthread_attr );
pthread_attr_setstack( &pthread_attr, teb->DeallocationStack,
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index f7aec55e355..4b4b90f4944 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -27,6 +27,11 @@
#include "wine/server.h"
#include "wine/list.h"
+#ifdef __APPLE__
+# include <mach/mach.h>
+# include <mach/semaphore.h>
+#endif
+
#ifdef __i386__
static const enum cpu_type client_cpu = CPU_x86;
#elif defined(__x86_64__)
@@ -58,10 +63,14 @@ 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 */
+#ifdef __APPLE__
+ semaphore_t tid_alert_sem; /* Mach semaphore for thread-id alerts */
+#else
#ifdef __linux__
int tid_alert_futex; /* futex for thread-id alerts */
#endif
HANDLE tid_alert_event; /* event for thread-id alerts */
+#endif
};
C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) );
--
2.20.1