ntdll: Implement condition variable functions using keyed events.

This commit is contained in:
Sebastian Lackner 2014-01-05 03:48:34 +01:00 committed by Alexandre Julliard
parent 86ffd6c4ea
commit 5472b9f9ca
3 changed files with 102 additions and 1 deletions

View File

@ -672,6 +672,7 @@
@ stdcall RtlInitUnicodeStringEx(ptr wstr)
# @ stub RtlInitializeAtomPackage
@ stdcall RtlInitializeBitMap(ptr long long)
@ stdcall RtlInitializeConditionVariable(ptr)
@ stub RtlInitializeContext
@ stdcall RtlInitializeCriticalSection(ptr)
@ stdcall RtlInitializeCriticalSectionAndSpinCount(ptr long)
@ -867,6 +868,7 @@
@ stub RtlSetUserFlagsHeap
@ stub RtlSetUserValueHeap
@ stdcall RtlSizeHeap(long long ptr)
@ stdcall RtlSleepConditionVariableCS(ptr ptr ptr)
@ stub RtlSplay
@ stub RtlStartRXact
# @ stub RtlStatMemoryStream
@ -932,6 +934,8 @@
# @ stub RtlValidateUnicodeString
@ stdcall RtlVerifyVersionInfo(ptr long int64)
@ stdcall -arch=x86_64 RtlVirtualUnwind(long long long ptr ptr ptr ptr ptr)
@ stdcall RtlWakeAllConditionVariable(ptr)
@ stdcall RtlWakeConditionVariable(ptr)
@ stub RtlWalkFrameChain
@ stdcall RtlWalkHeap(long ptr)
@ stdcall RtlWow64EnableFsRedirection(long)

View File

@ -63,6 +63,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
HANDLE keyed_event = NULL;
static inline int interlocked_dec_if_nonzero( int *dest )
{
int val, tmp;
for (val = *dest;; val = tmp)
{
if (!val || (tmp = interlocked_cmpxchg( dest, val - 1, val )) == val)
break;
}
return val;
}
/* creates a struct security_descriptor and contained information in one contiguous piece of memory */
NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd,
data_size_t *server_sd_len)
@ -1410,3 +1421,85 @@ void WINAPI RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
{
FIXME( "%p stub\n", lock );
}
/***********************************************************************
* RtlInitializeConditionVariable (NTDLL.@)
*
* Initializes the condition variable with NULL.
*
* PARAMS
* variable [O] condition variable
*
* RETURNS
* Nothing.
*/
void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable )
{
variable->Ptr = NULL;
}
/***********************************************************************
* RtlWakeConditionVariable (NTDLL.@)
*
* Wakes up one thread waiting on the condition variable.
*
* PARAMS
* variable [I/O] condition variable to wake up.
*
* RETURNS
* Nothing.
*
* NOTES
* The calling thread does not have to own any lock in order to call
* this function.
*/
void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable )
{
if (interlocked_dec_if_nonzero( (int *)&variable->Ptr ))
NtReleaseKeyedEvent( keyed_event, &variable->Ptr, FALSE, NULL );
}
/***********************************************************************
* RtlWakeAllConditionVariable (NTDLL.@)
*
* See WakeConditionVariable, wakes up all waiting threads.
*/
void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable )
{
int val = interlocked_xchg( (int *)&variable->Ptr, 0 );
while (val-- > 0)
NtReleaseKeyedEvent( keyed_event, &variable->Ptr, FALSE, NULL );
}
/***********************************************************************
* RtlSleepConditionVariableCS (NTDLL.@)
*
* Atomically releases the critical section and suspends the thread,
* waiting for a Wake(All)ConditionVariable event. Afterwards it enters
* the critical section again and returns.
*
* PARAMS
* variable [I/O] condition variable
* crit [I/O] critical section to leave temporarily
* timeout [I] timeout
*
* RETURNS
* see NtWaitForKeyedEvent for all possible return values.
*/
NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, RTL_CRITICAL_SECTION *crit,
const LARGE_INTEGER *timeout )
{
NTSTATUS status;
interlocked_xchg_add( (int *)&variable->Ptr, 1 );
RtlLeaveCriticalSection( crit );
status = NtWaitForKeyedEvent( keyed_event, &variable->Ptr, FALSE, timeout );
if (status != STATUS_SUCCESS)
{
if (!interlocked_dec_if_nonzero( (int *)&variable->Ptr ))
status = NtWaitForKeyedEvent( keyed_event, &variable->Ptr, FALSE, NULL );
}
RtlEnterCriticalSection( crit );
return status;
}

View File

@ -2418,10 +2418,11 @@ NTSYSAPI void WINAPI RtlInitAnsiString(PANSI_STRING,PCSZ);
NTSYSAPI NTSTATUS WINAPI RtlInitAnsiStringEx(PANSI_STRING,PCSZ);
NTSYSAPI void WINAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR);
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING,PCWSTR);
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP,PULONG,ULONG);
NTSYSAPI void WINAPI RtlInitializeConditionVariable(RTL_CONDITION_VARIABLE *);
NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSection(RTL_CRITICAL_SECTION *);
NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount(RTL_CRITICAL_SECTION *,ULONG);
NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionEx(RTL_CRITICAL_SECTION *,ULONG,ULONG);
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP,PULONG,ULONG);
NTSYSAPI void WINAPI RtlInitializeHandleTable(ULONG,ULONG,RTL_HANDLE_TABLE *);
NTSYSAPI void WINAPI RtlInitializeResource(LPRTL_RWLOCK);
NTSYSAPI void WINAPI RtlInitializeSRWLock(RTL_SRWLOCK*);
@ -2501,6 +2502,7 @@ NTSYSAPI NTSTATUS WINAPI RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOL
NTSYSAPI NTSTATUS WINAPI RtlSetThreadErrorMode(DWORD,LPDWORD);
NTSYSAPI NTSTATUS WINAPI RtlSetTimeZoneInformation(const RTL_TIME_ZONE_INFORMATION*);
NTSYSAPI SIZE_T WINAPI RtlSizeHeap(HANDLE,ULONG,const void*);
NTSYSAPI NTSTATUS WINAPI RtlSleepConditionVariableCS(RTL_CONDITION_VARIABLE*,RTL_CRITICAL_SECTION*,const LARGE_INTEGER*);
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID,PUNICODE_STRING);
NTSYSAPI LPDWORD WINAPI RtlSubAuthoritySid(PSID,DWORD);
NTSYSAPI LPBYTE WINAPI RtlSubAuthorityCountSid(PSID);
@ -2544,6 +2546,8 @@ NTSYSAPI BOOLEAN WINAPI RtlValidAcl(PACL);
NTSYSAPI BOOLEAN WINAPI RtlValidSid(PSID);
NTSYSAPI BOOLEAN WINAPI RtlValidateHeap(HANDLE,ULONG,LPCVOID);
NTSYSAPI NTSTATUS WINAPI RtlVerifyVersionInfo(const RTL_OSVERSIONINFOEXW*,DWORD,DWORDLONG);
NTSYSAPI void WINAPI RtlWakeAllConditionVariable(RTL_CONDITION_VARIABLE *);
NTSYSAPI void WINAPI RtlWakeConditionVariable(RTL_CONDITION_VARIABLE *);
NTSYSAPI NTSTATUS WINAPI RtlWalkHeap(HANDLE,PVOID);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirection(BOOLEAN);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx(ULONG,ULONG*);