ntdll: Read the condition variable and manipulate the lock on the PE side.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49712
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2020-08-20 15:38:42 -05:00 committed by Alexandre Julliard
parent 057e7f1940
commit 8bd95a80f2
5 changed files with 30 additions and 101 deletions

View file

@ -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 );

View file

@ -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,

View file

@ -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( &timespec, timeout );
ret = futex_wait( futex, val, &timespec );
}
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( &timespec, timeout );
ret = futex_wait( futex, aligned_value, &timespec );
}
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 );
ret = futex_wait( futex, aligned_value, NULL );
status = wait_cv( futex, val, timeout );
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,23 +2631,16 @@ 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 )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, int count )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value, const LARGE_INTEGER *timeout )
{
return STATUS_NOT_IMPLEMENTED;
}
static inline NTSTATUS fast_wait_addr( const void *addr, const void *cmp, SIZE_T size,
const LARGE_INTEGER *timeout )
{

View file

@ -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;

View file

@ -28,7 +28,7 @@ struct msghdr;
struct _DISPATCHER_CONTEXT;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 93
#define NTDLL_UNIXLIB_VERSION 94
struct unix_funcs
{
@ -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 );