Module: wine Branch: master Commit: 2c903e9e9bb1254a9fbed60767b56668e675f64e URL: https://source.winehq.org/git/wine.git/?a=commit;h=2c903e9e9bb1254a9fbed6076...
Author: Alexandre Julliard julliard@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@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__