Alexandre Julliard : ntdll: Move the critical section fallback code out of the Unix library.

Alexandre Julliard julliard at winehq.org
Mon Aug 3 16:35:36 CDT 2020


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Aug  3 15:52:05 2020 +0200

ntdll: Move the critical section fallback code out of the Unix library.

This partially reverts commit ff19f21913c508f5827df0e7e4c3a351c36711a0.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/critsection.c | 53 ++++++++++++++++++++++++++++++++++---
 dlls/ntdll/unix/sync.c   | 69 +++++-------------------------------------------
 2 files changed, 55 insertions(+), 67 deletions(-)

diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c
index 232d6aa06c..fe7d933c0f 100644
--- a/dlls/ntdll/critsection.c
+++ b/dlls/ntdll/critsection.c
@@ -50,6 +50,44 @@ static BOOL crit_section_has_debuginfo(const RTL_CRITICAL_SECTION *crit)
     return crit->DebugInfo != NULL && crit->DebugInfo != no_debug_info_marker;
 }
 
+/***********************************************************************
+ *           get_semaphore
+ */
+static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
+{
+    HANDLE ret = crit->LockSemaphore;
+    if (!ret)
+    {
+        HANDLE sem;
+        if (NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 )) return 0;
+        if (!(ret = InterlockedCompareExchangePointer( &crit->LockSemaphore, sem, 0 )))
+            ret = sem;
+        else
+            NtClose(sem);  /* somebody beat us to it */
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *           wait_semaphore
+ */
+static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
+{
+    NTSTATUS ret;
+
+    /* debug info is cleared by MakeCriticalSectionGlobal */
+    if (!crit_section_has_debuginfo( crit ) ||
+        ((ret = unix_funcs->fast_RtlpWaitForCriticalSection( crit, timeout )) == STATUS_NOT_IMPLEMENTED))
+    {
+        HANDLE sem = get_semaphore( crit );
+        LARGE_INTEGER time;
+
+        time.QuadPart = timeout * (LONGLONG)-10000000;
+        ret = NtWaitForSingleObject( sem, FALSE, &time );
+    }
+    return ret;
+}
+
 /***********************************************************************
  *           RtlInitializeCriticalSection   (NTDLL.@)
  *
@@ -260,7 +298,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
     for (;;)
     {
         EXCEPTION_RECORD rec;
-        NTSTATUS status = unix_funcs->fast_RtlpWaitForCriticalSection( crit, 5 );
+        NTSTATUS status = wait_semaphore( crit, 5 );
         timeout -= 5;
 
         if ( status == STATUS_TIMEOUT )
@@ -270,14 +308,14 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
             if (!name) name = "?";
             ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (60 sec)\n",
                  crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) );
-            status = unix_funcs->fast_RtlpWaitForCriticalSection( crit, 60 );
+            status = wait_semaphore( crit, 60 );
             timeout -= 60;
 
             if ( status == STATUS_TIMEOUT && TRACE_ON(relay) )
             {
                 ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (5 min)\n",
                      crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) );
-                status = unix_funcs->fast_RtlpWaitForCriticalSection( crit, 300 );
+                status = wait_semaphore( crit, 300 );
                 timeout -= 300;
             }
         }
@@ -327,8 +365,15 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
  */
 NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
 {
-    NTSTATUS ret = unix_funcs->fast_RtlpUnWaitCriticalSection( crit );
+    NTSTATUS ret;
 
+    /* debug info is cleared by MakeCriticalSectionGlobal */
+    if (!crit_section_has_debuginfo( crit ) ||
+        ((ret = unix_funcs->fast_RtlpUnWaitCriticalSection( crit )) == STATUS_NOT_IMPLEMENTED))
+    {
+        HANDLE sem = get_semaphore( crit );
+        ret = NtReleaseSemaphore( sem, 1, NULL );
+    }
     if (ret) RtlRaiseStatus( ret );
     return ret;
 }
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 2dc1a7c2aa..e7e13a6c7e 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -2129,16 +2129,9 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
 }
 
 
-static void *no_debug_info_marker = (void *)(ULONG_PTR)-1;
-
-static BOOL crit_section_has_debuginfo(const RTL_CRITICAL_SECTION *crit)
-{
-    return crit->DebugInfo != NULL && crit->DebugInfo != no_debug_info_marker;
-}
-
 #ifdef __linux__
 
-static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int timeout )
+NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
 {
     int val;
     struct timespec timespec;
@@ -2157,7 +2150,7 @@ static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int ti
     return STATUS_WAIT_0;
 }
 
-static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
+NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
 {
     if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
 
@@ -2189,7 +2182,7 @@ static inline semaphore_t get_mach_semaphore( RTL_CRITICAL_SECTION *crit )
     return ret;
 }
 
-static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int timeout )
+NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
 {
     mach_timespec_t timespec;
     semaphore_t sem = get_mach_semaphore( crit );
@@ -2212,7 +2205,7 @@ static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int ti
     }
 }
 
-static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
+NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
 {
     semaphore_t sem = get_mach_semaphore( crit );
     semaphore_signal( sem );
@@ -2227,12 +2220,12 @@ NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
 
 #else  /* __APPLE__ */
 
-static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int timeout )
+NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
 {
     return STATUS_NOT_IMPLEMENTED;
 }
 
-static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
+NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
 {
     return STATUS_NOT_IMPLEMENTED;
 }
@@ -2244,56 +2237,6 @@ NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
 
 #endif
 
-static inline HANDLE get_critsection_semaphore( RTL_CRITICAL_SECTION *crit )
-{
-    HANDLE ret = crit->LockSemaphore;
-    if (!ret)
-    {
-        HANDLE sem;
-        if (NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 )) return 0;
-        if (!(ret = InterlockedCompareExchangePointer( &crit->LockSemaphore, sem, 0 )))
-            ret = sem;
-        else
-            NtClose( sem );  /* somebody beat us to it */
-    }
-    return ret;
-}
-
-NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
-{
-    NTSTATUS ret;
-
-    /* debug info is cleared by MakeCriticalSectionGlobal */
-    if (!crit_section_has_debuginfo( crit ) ||
-        ((ret = fast_critsection_wait( crit, timeout )) == STATUS_NOT_IMPLEMENTED))
-    {
-        HANDLE sem = get_critsection_semaphore( crit );
-        LARGE_INTEGER time;
-        select_op_t select_op;
-
-        time.QuadPart = timeout * (LONGLONG)-10000000;
-        select_op.wait.op = SELECT_WAIT;
-        select_op.wait.handles[0] = wine_server_obj_handle( sem );
-        ret = server_wait( &select_op, offsetof( select_op_t, wait.handles[1] ), 0, &time );
-    }
-    return ret;
-}
-
-NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
-{
-    NTSTATUS ret;
-
-    /* debug info is cleared by MakeCriticalSectionGlobal */
-    if (!crit_section_has_debuginfo( crit ) ||
-        ((ret = fast_critsection_wake( crit )) == STATUS_NOT_IMPLEMENTED))
-    {
-        HANDLE sem = get_critsection_semaphore( crit );
-        ret = NtReleaseSemaphore( sem, 1, NULL );
-    }
-    return ret;
-}
-
-
 
 #ifdef __linux__
 




More information about the wine-cvs mailing list