From: Yuxuan Shui yshui@codeweavers.com
There are applications that uses SRWLOCK in an invalid way and then checks its binary representation. Tweak our representation a bit so they are happy. --- dlls/kernel32/tests/sync.c | 20 ++++++++++++++++++++ dlls/ntdll/sync.c | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c index 10765765bc5..6c0f2280f78 100644 --- a/dlls/kernel32/tests/sync.c +++ b/dlls/kernel32/tests/sync.c @@ -2535,6 +2535,25 @@ static void test_srwlock_example(void) trace("number of total exclusive accesses is %ld\n", srwlock_protected_value); }
+static void test_srwlock_quirk(void) +{ + union { SRWLOCK *s; LONG *l; } u = { &srwlock_example }; + + if (!pInitializeSRWLock) { + /* function is not yet in XP, only in newer Windows */ + win_skip("no srw lock support.\n"); + return; + } + + *u.l = 0; + pReleaseSRWLockExclusive(&srwlock_example); + ok(*u.l == 0xffffffff, "expected 0xffffffff, got %lx\n", *u.l); + + *u.l = 1; + pReleaseSRWLockExclusive(&srwlock_example); + ok(*u.l == 0, "expected 0x0, got %lx\n", *u.l); +} + static DWORD WINAPI alertable_wait_thread(void *param) { HANDLE *semaphores = param; @@ -2887,6 +2906,7 @@ START_TEST(sync) test_condvars_base(&unaligned_cv.cv); test_condvars_consumer_producer(); test_srwlock_base(&aligned_srwlock); + test_srwlock_quirk(); #if defined(__i386__) || defined(__x86_64__) /* unaligned locks only work on x86 platforms */ test_srwlock_base(&unaligned_srwlock.lock); diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index fa64917029a..90370abba09 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -473,8 +473,6 @@ DWORD WINAPI RtlRunOnceExecuteOnce( RTL_RUN_ONCE *once, PRTL_RUN_ONCE_INIT_FN fu
struct srw_lock { - short exclusive_waiters; - /* Number of shared owners, or -1 if owned exclusive. * * Sadly Windows has no equivalent to FUTEX_WAIT_BITSET, so in order to wake @@ -487,6 +485,8 @@ struct srw_lock * must not be the first element in the structure. */ short owners; + + short exclusive_waiters; }; C_ASSERT( sizeof(struct srw_lock) == 4 );