From 869e78931ae6cf9039c07758d66041ec168eea8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net> Date: Thu, 18 Jan 2024 18:26:17 -0500 Subject: [PATCH] Fix rwlocks for Win32 Various bits of broken no longer broken. --- src/xpdev/rwlockwrap.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/xpdev/rwlockwrap.c b/src/xpdev/rwlockwrap.c index bc3046b196..519913599b 100644 --- a/src/xpdev/rwlockwrap.c +++ b/src/xpdev/rwlockwrap.c @@ -3,6 +3,7 @@ #if defined(_WIN32) #include <stdlib.h> +#include <stdio.h> static struct rwlock_reader_thread * find_self(rwlock_t *lock, struct rwlock_reader_thread ***prev) @@ -12,7 +13,7 @@ find_self(rwlock_t *lock, struct rwlock_reader_thread ***prev) if (prev) *prev = &lock->rthreads; - for (ret = NULL; ret; ret = ret->next) { + for (ret = lock->rthreads; ret; ret = ret->next) { if (ret->id == self) return ret; if (prev) { @@ -94,7 +95,7 @@ rwlock_tryrdlock(rwlock_t *lock) LeaveCriticalSection(&lock->lk); return FALSE; } - if (lock->writers == 0 && lock->writers_waiting == 0) { + if (rc->count || (lock->writers == 0 && lock->writers_waiting == 0)) { rc->count++; lock->readers++; ret = TRUE; @@ -106,23 +107,33 @@ rwlock_tryrdlock(rwlock_t *lock) BOOL rwlock_wrlock(rwlock_t *lock) { + BOOL ret = FALSE; EnterCriticalSection(&lock->lk); lock->writers_waiting++; LeaveCriticalSection(&lock->lk); EnterCriticalSection(&lock->wlk); EnterCriticalSection(&lock->lk); // No recursion - if (lock->writers == 0) { + while (lock->readers) { + LeaveCriticalSection(&lock->lk); + LeaveCriticalSection(&lock->wlk); + Sleep(1); + EnterCriticalSection(&lock->wlk); + EnterCriticalSection(&lock->lk); + } + if (lock->writers) { + lock->writers_waiting--; + ret = FALSE; + } + else { lock->writers_waiting--; lock->writers++; lock->writer = GetCurrentThreadId(); - LeaveCriticalSection(&lock->lk); - // Keep holding wlk - return TRUE; + ret = TRUE; } LeaveCriticalSection(&lock->lk); LeaveCriticalSection(&lock->wlk); - return FALSE; + return ret; } BOOL @@ -131,7 +142,7 @@ rwlock_trywrlock(rwlock_t *lock) if (TryEnterCriticalSection(&lock->wlk)) { EnterCriticalSection(&lock->lk); // Prevent recursing on writer locks - if (lock->writers == 0) { + if (lock->readers == 0 && lock->writers == 0) { lock->writers++; lock->writer = GetCurrentThreadId(); LeaveCriticalSection(&lock->lk); @@ -163,7 +174,7 @@ rwlock_unlock(rwlock_t *lock) return FALSE; } if (lock->readers) { - rc = find_self(lock, NULL); + rc = find_self(lock, &prev); if (rc && rc->count) { rc->count--; lock->readers--; -- GitLab