feature: implement win32 read-write lock synchronization primitive

This commit is contained in:
MechSlayer 2025-09-05 15:48:13 +02:00
parent 9ad553ea6e
commit 606fd13447
2 changed files with 118 additions and 1 deletions

View file

@ -14,4 +14,10 @@ struct drang_cond
{
CONDITION_VARIABLE cv;
bool initialized;
};
};
struct drang_rwlock
{
SRWLOCK srw;
bool initialized;
};

View file

@ -0,0 +1,111 @@
#include <drang/alloc.h>
#include <drang/sync.h>
#include "internal.h"
size_t drang_rwlock_size(void)
{
return sizeof(struct drang_rwlock);
}
int drang_rwlock_new(struct drang_rwlock **rwlock)
{
struct drang_rwlock *rw = NULL;
DRANG_BEGIN_TRY();
DRANG_CHECK(rwlock != NULL, DRANG_EINVAL);
rw = DRANG_TRY_ALLOC_T(struct drang_rwlock);
DRANG_TRY(drang_rwlock_init(rw));
DRANG_RETURN_IN(rwlock, rw);
DRANG_CATCH(_)
{
if (rw != NULL) {
drang_free(rw);
}
}
DRANG_END_TRY();
}
void drang_rwlock_free(struct drang_rwlock *rwlock)
{
if (rwlock == NULL) {
return;
}
drang_rwlock_fini(rwlock);
drang_free(rwlock);
}
int drang_rwlock_init(struct drang_rwlock *rwlock)
{
DRANG_BEGIN_TRY();
DRANG_CHECK(rwlock != NULL, DRANG_EINVAL);
DRANG_CHECK(!rwlock->initialized, DRANG_EBUSY);
InitializeSRWLock(&rwlock->srw);
rwlock->initialized = true;
DRANG_END_TRY_IGNORE();
}
void drang_rwlock_fini(struct drang_rwlock *rwlock)
{
if (rwlock == NULL) {
return;
}
// Windows SRWLOCK doesn't require explicit cleanup
rwlock->initialized = false;
}
int drang_rwlock_rdlock(struct drang_rwlock *rwlock)
{
DRANG_BEGIN_TRY();
DRANG_CHECK(rwlock != NULL, DRANG_EINVAL);
DRANG_CHECK(rwlock->initialized, DRANG_EINVAL);
AcquireSRWLockShared(&rwlock->srw);
DRANG_END_TRY_IGNORE();
}
int drang_rwlock_wrlock(struct drang_rwlock *rwlock)
{
DRANG_BEGIN_TRY();
DRANG_CHECK(rwlock != NULL, DRANG_EINVAL);
DRANG_CHECK(rwlock->initialized, DRANG_EINVAL);
AcquireSRWLockExclusive(&rwlock->srw);
DRANG_END_TRY_IGNORE();
}
int drang_rwlock_rdunlock(struct drang_rwlock *rwlock)
{
DRANG_BEGIN_TRY();
DRANG_CHECK(rwlock != NULL, DRANG_EINVAL);
DRANG_CHECK(rwlock->initialized, DRANG_EINVAL);
ReleaseSRWLockShared(&rwlock->srw);
DRANG_END_TRY_IGNORE();
}
int drang_rwlock_wrunlock(struct drang_rwlock *rwlock)
{
DRANG_BEGIN_TRY();
DRANG_CHECK(rwlock != NULL, DRANG_EINVAL);
DRANG_CHECK(rwlock->initialized, DRANG_EINVAL);
ReleaseSRWLockExclusive(&rwlock->srw);
DRANG_END_TRY_IGNORE();
}