mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
140 lines
4.4 KiB
Diff
140 lines
4.4 KiB
Diff
From 32902deea99f78645f82f283f5cde453607cec1d 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 bfcd7bf04a7..9b3c9a91abc 100644
|
|
--- a/dlls/ntdll/unix/thread.c
|
|
+++ b/dlls/ntdll/unix/thread.c
|
|
@@ -262,7 +262,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 4c38ed8ef29..3d629de09b2 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 WORD current_machine = IMAGE_FILE_MACHINE_I386;
|
|
#elif defined(__x86_64__)
|
|
@@ -60,10 +65,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.30.2
|
|
|