Zebediah Figura : ntdll: Implement thread-ID alerts using Mach semaphores on Mac.

Alexandre Julliard julliard at winehq.org
Thu Nov 18 16:19:37 CST 2021


Module: wine
Branch: master
Commit: 842ecb45f433d458220eaefa6bedb3e3ed635deb
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=842ecb45f433d458220eaefa6bedb3e3ed635deb

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Wed Nov 17 20:18:53 2021 -0600

ntdll: Implement thread-ID alerts using Mach semaphores on Mac.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/sync.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 59fe6bea8f5..cdc63c8a6ef 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -2341,10 +2341,14 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
 
 union tid_alert_entry
 {
+#ifdef __APPLE__
+    semaphore_t sem;
+#else
     HANDLE event;
 #ifdef __linux__
     int futex;
 #endif
+#endif
 };
 
 #define TID_ALERT_BLOCK_SIZE (65536 / sizeof(union tid_alert_entry))
@@ -2379,6 +2383,17 @@ static union tid_alert_entry *get_tid_alert_entry( HANDLE tid )
 
     entry = &tid_alert_blocks[block_idx][idx % TID_ALERT_BLOCK_SIZE];
 
+#ifdef __APPLE__
+    if (!entry->sem)
+    {
+        semaphore_t sem;
+
+        if (semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, 0 ))
+            return NULL;
+        if (InterlockedCompareExchange( (int *)&entry->sem, sem, NULL ))
+            semaphore_destroy( mach_task_self(), sem );
+    }
+#else
 #ifdef __linux__
     if (use_futexes())
         return entry;
@@ -2393,6 +2408,7 @@ static union tid_alert_entry *get_tid_alert_entry( HANDLE tid )
         if (InterlockedCompareExchangePointer( &entry->event, event, NULL ))
             NtClose( event );
     }
+#endif
 
     return entry;
 }
@@ -2409,6 +2425,10 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
 
     if (!entry) return STATUS_INVALID_CID;
 
+#ifdef __APPLE__
+    semaphore_signal( entry->sem );
+    return STATUS_SUCCESS;
+#else
 #ifdef __linux__
     if (use_futexes())
     {
@@ -2420,10 +2440,11 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
 #endif
 
     return NtSetEvent( entry->event, NULL );
+#endif
 }
 
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__APPLE__)
 static LONGLONG get_absolute_timeout( const LARGE_INTEGER *timeout )
 {
     LARGE_INTEGER now;
@@ -2446,6 +2467,57 @@ static LONGLONG update_timeout( ULONGLONG end )
 #endif
 
 
+#ifdef __APPLE__
+
+/***********************************************************************
+ *             NtWaitForAlertByThreadId (NTDLL.@)
+ */
+NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout )
+{
+    union tid_alert_entry *entry = get_tid_alert_entry( NtCurrentTeb()->ClientId.UniqueThread );
+    semaphore_t sem;
+    ULONGLONG end;
+    kern_return_t ret;
+
+    TRACE( "%p %s\n", address, debugstr_timeout( timeout ) );
+
+    if (!entry) return STATUS_INVALID_CID;
+    sem = entry->sem;
+
+    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
+
 /***********************************************************************
  *             NtWaitForAlertByThreadId (NTDLL.@)
  */
@@ -2498,6 +2570,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
     return status;
 }
 
+#endif
 
 #ifdef __linux__
 




More information about the wine-cvs mailing list