[PATCH] ntdll: Read the condition variable and manipulate the lock on the PE side.
Zebediah Figura
z.figura12 at gmail.com
Thu Aug 20 15:38:42 CDT 2020
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49712
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/ntdll/sync.c | 21 +++------
dlls/ntdll/unix/loader.c | 3 +-
dlls/ntdll/unix/sync.c | 84 ++++++----------------------------
dlls/ntdll/unix/unix_private.h | 7 +--
dlls/ntdll/unixlib.h | 8 +---
5 files changed, 26 insertions(+), 97 deletions(-)
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index edbdd91c1b9..8df7015df9f 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -481,16 +481,12 @@ void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable )
NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, RTL_CRITICAL_SECTION *crit,
const LARGE_INTEGER *timeout )
{
+ const void *value = variable->Ptr;
NTSTATUS status;
- int val;
- if ((status = unix_funcs->fast_RtlSleepConditionVariableCS( variable, crit,
- timeout )) != STATUS_NOT_IMPLEMENTED)
- return status;
-
- val = *(int *)&variable->Ptr;
RtlLeaveCriticalSection( crit );
- status = RtlWaitOnAddress( &variable->Ptr, &val, sizeof(int), timeout );
+ if ((status = unix_funcs->fast_wait_cv( variable, value, timeout )) == STATUS_NOT_IMPLEMENTED)
+ status = RtlWaitOnAddress( &variable->Ptr, &value, sizeof(value), timeout );
RtlEnterCriticalSection( crit );
return status;
}
@@ -517,21 +513,16 @@ NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, R
NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, RTL_SRWLOCK *lock,
const LARGE_INTEGER *timeout, ULONG flags )
{
+ const void *value = variable->Ptr;
NTSTATUS status;
- int val;
-
- if ((status = unix_funcs->fast_RtlSleepConditionVariableSRW( variable, lock, timeout,
- flags )) != STATUS_NOT_IMPLEMENTED)
- return status;
-
- val = *(int *)&variable->Ptr;
if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED)
RtlReleaseSRWLockShared( lock );
else
RtlReleaseSRWLockExclusive( lock );
- status = RtlWaitOnAddress( &variable->Ptr, &val, sizeof(int), timeout );
+ if ((status = unix_funcs->fast_wait_cv( variable, value, timeout )) == STATUS_NOT_IMPLEMENTED)
+ status = RtlWaitOnAddress( variable, &value, sizeof(value), timeout );
if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED)
RtlAcquireSRWLockShared( lock );
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index e7cc050ba9d..1424bf3cc6a 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -1383,9 +1383,8 @@ static struct unix_funcs unix_funcs =
fast_RtlAcquireSRWLockShared,
fast_RtlReleaseSRWLockExclusive,
fast_RtlReleaseSRWLockShared,
- fast_RtlSleepConditionVariableSRW,
- fast_RtlSleepConditionVariableCS,
fast_RtlWakeConditionVariable,
+ fast_wait_cv,
ntdll_atan,
ntdll_ceil,
ntdll_cos,
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 23dca9c61b3..18e64b02627 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -2490,81 +2490,34 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
return STATUS_SUCCESS;
}
-static NTSTATUS wait_cv( int *futex, int val, const LARGE_INTEGER *timeout )
+NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value, const LARGE_INTEGER *timeout )
{
+ const char *value_ptr;
+ int aligned_value, *futex;
struct timespec timespec;
int ret;
- if (timeout && timeout->QuadPart != TIMEOUT_INFINITE)
- {
- timespec_from_timeout( ×pec, timeout );
- ret = futex_wait( futex, val, ×pec );
- }
- else
- ret = futex_wait( futex, val, NULL );
-
- if (ret == -1 && errno == ETIMEDOUT)
- return STATUS_TIMEOUT;
- return STATUS_WAIT_0;
-}
-
-NTSTATUS CDECL fast_RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable,
- RTL_CRITICAL_SECTION *cs, const LARGE_INTEGER *timeout )
-{
- NTSTATUS status;
- int val, *futex;
-
if (!use_futexes())
return STATUS_NOT_IMPLEMENTED;
if (!(futex = get_futex( &variable->Ptr )))
return STATUS_NOT_IMPLEMENTED;
- val = *futex;
+ value_ptr = (const char *)&value;
+ value_ptr += ((ULONG_PTR)futex) - ((ULONG_PTR)&variable->Ptr);
+ aligned_value = *(int *)value_ptr;
- if (cs->RecursionCount == 1)
+ if (timeout && timeout->QuadPart != TIMEOUT_INFINITE)
{
- /* FIXME: simplified version of RtlLeaveCriticalSection/RtlEnterCriticalSection to avoid imports */
- cs->RecursionCount = 0;
- cs->OwningThread = 0;
- if (InterlockedDecrement( &cs->LockCount ) >= 0) fast_RtlpUnWaitCriticalSection( cs );
-
- status = wait_cv( futex, val, timeout );
-
- if (InterlockedIncrement( &cs->LockCount )) fast_RtlpWaitForCriticalSection( cs, INT_MAX );
- cs->OwningThread = ULongToHandle( GetCurrentThreadId() );
- cs->RecursionCount = 1;
+ timespec_from_timeout( ×pec, timeout );
+ ret = futex_wait( futex, aligned_value, ×pec );
}
- else status = wait_cv( futex, val, timeout );
- return status;
-}
-
-NTSTATUS CDECL fast_RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, RTL_SRWLOCK *lock,
- const LARGE_INTEGER *timeout, ULONG flags )
-{
- NTSTATUS status;
- int val, *futex;
-
- if (!use_futexes())
- return STATUS_NOT_IMPLEMENTED;
-
- if (!(futex = get_futex( &variable->Ptr )) || !get_futex( &lock->Ptr ))
- return STATUS_NOT_IMPLEMENTED;
-
- val = *futex;
-
- if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED)
- fast_RtlReleaseSRWLockShared( lock );
else
- fast_RtlReleaseSRWLockExclusive( lock );
-
- status = wait_cv( futex, val, timeout );
+ ret = futex_wait( futex, aligned_value, NULL );
- if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED)
- fast_RtlAcquireSRWLockShared( lock );
- else
- fast_RtlAcquireSRWLockExclusive( lock );
- return status;
+ if (ret == -1 && errno == ETIMEDOUT)
+ return STATUS_TIMEOUT;
+ return STATUS_WAIT_0;
}
NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, int count )
@@ -2678,19 +2631,12 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
return STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS CDECL fast_RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, RTL_SRWLOCK *lock,
- const LARGE_INTEGER *timeout, ULONG flags )
-{
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS CDECL fast_RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable,
- RTL_CRITICAL_SECTION *cs, const LARGE_INTEGER *timeout )
+NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, int count )
{
return STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, int count )
+NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value, const LARGE_INTEGER *timeout )
{
return STATUS_NOT_IMPLEMENTED;
}
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 397211957bd..1d3d58b2533 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -98,13 +98,10 @@ extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLS
extern NTSTATUS CDECL fast_RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL fast_RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
-extern NTSTATUS CDECL fast_RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, RTL_SRWLOCK *lock,
- const LARGE_INTEGER *timeout, ULONG flags ) DECLSPEC_HIDDEN;
-extern NTSTATUS CDECL fast_RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable,
- RTL_CRITICAL_SECTION *cs,
- const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, int count ) DECLSPEC_HIDDEN;
extern LONGLONG CDECL fast_RtlGetSystemTimePrecise(void) DECLSPEC_HIDDEN;
+extern NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value,
+ const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
void CDECL mmap_add_reserved_area( void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
void CDECL mmap_remove_reserved_area( void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h
index 2f57873671c..2af1bc6ac98 100644
--- a/dlls/ntdll/unixlib.h
+++ b/dlls/ntdll/unixlib.h
@@ -53,13 +53,9 @@ struct unix_funcs
NTSTATUS (CDECL *fast_RtlAcquireSRWLockShared)( RTL_SRWLOCK *lock );
NTSTATUS (CDECL *fast_RtlReleaseSRWLockExclusive)( RTL_SRWLOCK *lock );
NTSTATUS (CDECL *fast_RtlReleaseSRWLockShared)( RTL_SRWLOCK *lock );
- NTSTATUS (CDECL *fast_RtlSleepConditionVariableSRW)( RTL_CONDITION_VARIABLE *variable,
- RTL_SRWLOCK *lock,
- const LARGE_INTEGER *timeout, ULONG flags );
- NTSTATUS (CDECL *fast_RtlSleepConditionVariableCS)( RTL_CONDITION_VARIABLE *variable,
- RTL_CRITICAL_SECTION *cs,
- const LARGE_INTEGER *timeout );
NTSTATUS (CDECL *fast_RtlWakeConditionVariable)( RTL_CONDITION_VARIABLE *variable, int count );
+ NTSTATUS (CDECL *fast_wait_cv)( RTL_CONDITION_VARIABLE *variable, const void *value,
+ const LARGE_INTEGER *timeout );
/* math functions */
double (CDECL *atan)( double d );
--
2.28.0
More information about the wine-devel
mailing list