From 899fc8d4eeb2f442eeed4ea122ac92f78208a994 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 21 Jan 2014 22:18:10 +0100 Subject: [PATCH] ntdll: Implement RtlTryAcquireSRWLockShared/Exclusive commands. --- dlls/ntdll/ntdll.spec | 2 ++ dlls/ntdll/sync.c | 33 +++++++++++++++++++++++++++++++++ include/winternl.h | 2 ++ 3 files changed, 37 insertions(+) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 2e507bb5c6..4140ff9f81 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -891,6 +891,8 @@ # @ stub RtlTraceDatabaseLock # @ stub RtlTraceDatabaseUnlock # @ stub RtlTraceDatabaseValidate +@ stdcall RtlTryAcquireSRWLockExclusive(ptr) +@ stdcall RtlTryAcquireSRWLockShared(ptr) @ stdcall RtlTryEnterCriticalSection(ptr) @ cdecl -i386 -norelay RtlUlongByteSwap() NTDLL_RtlUlongByteSwap @ cdecl -ret64 RtlUlonglongByteSwap(int64) diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 7d18d20bd6..6404ac5926 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -1535,6 +1535,10 @@ void WINAPI RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) /*********************************************************************** * RtlAcquireSRWLockShared (NTDLL.@) + * + * NOTES + * Do not call this function recursively - it will only succeed when + * there are no threads waiting for an exclusive lock! */ void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) { @@ -1582,6 +1586,35 @@ void WINAPI RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) - SRWLOCK_RES_SHARED ) - SRWLOCK_RES_SHARED ); } +/*********************************************************************** + * RtlTryAcquireSRWLockExclusive (NTDLL.@) + * + * NOTES + * Similar to AcquireSRWLockExclusive recusive calls are not allowed + * and will fail with return value FALSE. + */ +BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) +{ + return interlocked_cmpxchg( (int *)&lock->Ptr, SRWLOCK_MASK_IN_EXCLUSIVE | + SRWLOCK_RES_EXCLUSIVE, 0 ) == 0; +} + +/*********************************************************************** + * RtlTryAcquireSRWLockShared (NTDLL.@) + */ +BOOLEAN WINAPI RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) +{ + unsigned int val, tmp; + for (val = *(unsigned int *)&lock->Ptr;; val = tmp) + { + if (val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) + return FALSE; + if ((tmp = interlocked_cmpxchg( (int *)&lock->Ptr, val + SRWLOCK_RES_SHARED, val )) == val) + break; + } + return TRUE; +} + /*********************************************************************** * RtlInitializeConditionVariable (NTDLL.@) * diff --git a/include/winternl.h b/include/winternl.h index c84073242c..d3a02bfc9a 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2512,6 +2512,8 @@ NTSYSAPI BOOLEAN WINAPI RtlTimeFieldsToTime(PTIME_FIELDS,PLARGE_INTEGER); NTSYSAPI void WINAPI RtlTimeToElapsedTimeFields(const LARGE_INTEGER *,PTIME_FIELDS); NTSYSAPI BOOLEAN WINAPI RtlTimeToSecondsSince1970(const LARGE_INTEGER *,LPDWORD); NTSYSAPI BOOLEAN WINAPI RtlTimeToSecondsSince1980(const LARGE_INTEGER *,LPDWORD); +NTSYSAPI BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive(RTL_SRWLOCK *); +NTSYSAPI BOOLEAN WINAPI RtlTryAcquireSRWLockShared(RTL_SRWLOCK *); NTSYSAPI BOOL WINAPI RtlTryEnterCriticalSection(RTL_CRITICAL_SECTION *); NTSYSAPI ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG); NTSYSAPI DWORD WINAPI RtlUnicodeStringToAnsiSize(const UNICODE_STRING*);