Module: wine Branch: master Commit: 954ed39584ba30fe194558cfbafa84aa1d3b2844 URL: https://source.winehq.org/git/wine.git/?a=commit;h=954ed39584ba30fe194558cfb...
Author: Zebediah Figura z.figura12@gmail.com Date: Thu Feb 7 12:39:46 2019 -0600
ntdll: Reimplement condition variables on top of RtlWaitOnAddress().
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46208 Signed-off-by: Zebediah Figura z.figura12@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/sync.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-)
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 8513561..693013f 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -1909,8 +1909,8 @@ void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable ) */ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable ) { - if (interlocked_dec_if_nonzero( (int *)&variable->Ptr )) - NtReleaseKeyedEvent( 0, &variable->Ptr, FALSE, NULL ); + interlocked_xchg_add( (int *)&variable->Ptr, 1 ); + RtlWakeAddressSingle( variable ); }
/*********************************************************************** @@ -1920,9 +1920,8 @@ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable ) */ void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable ) { - int val = interlocked_xchg( (int *)&variable->Ptr, 0 ); - while (val-- > 0) - NtReleaseKeyedEvent( 0, &variable->Ptr, FALSE, NULL ); + interlocked_xchg_add( (int *)&variable->Ptr, 1 ); + RtlWakeAddressAll( variable ); }
/*********************************************************************** @@ -1944,17 +1943,14 @@ NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, R const LARGE_INTEGER *timeout ) { NTSTATUS status; - interlocked_xchg_add( (int *)&variable->Ptr, 1 ); + int val = *(int *)&variable->Ptr; + RtlLeaveCriticalSection( crit );
- status = NtWaitForKeyedEvent( 0, &variable->Ptr, FALSE, timeout ); - if (status != STATUS_SUCCESS) - { - if (!interlocked_dec_if_nonzero( (int *)&variable->Ptr )) - status = NtWaitForKeyedEvent( 0, &variable->Ptr, FALSE, NULL ); - } + status = RtlWaitOnAddress( &variable->Ptr, &val, sizeof(int), timeout );
RtlEnterCriticalSection( crit ); + return status; }
@@ -1981,19 +1977,14 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, const LARGE_INTEGER *timeout, ULONG flags ) { NTSTATUS status; - interlocked_xchg_add( (int *)&variable->Ptr, 1 ); + int val = *(int *)&variable->Ptr;
if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) RtlReleaseSRWLockShared( lock ); else RtlReleaseSRWLockExclusive( lock );
- status = NtWaitForKeyedEvent( 0, &variable->Ptr, FALSE, timeout ); - if (status != STATUS_SUCCESS) - { - if (!interlocked_dec_if_nonzero( (int *)&variable->Ptr )) - status = NtWaitForKeyedEvent( 0, &variable->Ptr, FALSE, NULL ); - } + status = RtlWaitOnAddress( &variable->Ptr, &val, sizeof(int), timeout );
if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) RtlAcquireSRWLockShared( lock );