diff --git a/Source/DrangPlatform/Source/win32/sync/internal.h b/Source/DrangPlatform/Source/win32/sync/internal.h index 542b7a2..e1ed6b7 100644 --- a/Source/DrangPlatform/Source/win32/sync/internal.h +++ b/Source/DrangPlatform/Source/win32/sync/internal.h @@ -14,4 +14,10 @@ struct drang_cond { CONDITION_VARIABLE cv; bool initialized; -}; \ No newline at end of file +}; + +struct drang_rwlock +{ + SRWLOCK srw; + bool initialized; +}; diff --git a/Source/DrangPlatform/Source/win32/sync/rwlock.c b/Source/DrangPlatform/Source/win32/sync/rwlock.c new file mode 100644 index 0000000..599ca02 --- /dev/null +++ b/Source/DrangPlatform/Source/win32/sync/rwlock.c @@ -0,0 +1,111 @@ +#include +#include +#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(); +}