/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuMutex.Win32.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "AuMutex.Generic.hpp" #if !defined(_AURUNTIME_GENERICMUTEX) #include "AuMutex.NT.hpp" namespace Aurora::Threading::Primitives { Mutex::Mutex() { InitializeSRWLock(&this->atomicHolder_); InitializeConditionVariable(&this->wakeup_); this->state_ = 0; } Mutex::~Mutex() { } bool Mutex::HasOSHandle(AuMach &mach) { return false; } bool Mutex::TryLock() { return _interlockedbittestandset(&this->state_, 0) == 0; } bool Mutex::HasLockImplementation() { return true; } void Mutex::Lock() { auto status = Lock(0); SysAssert(status, "Couldn't lock Mutex object"); } bool Mutex::Lock(AuUInt64 timeout) { bool returnValue = false; AcquireSRWLockShared(&this->atomicHolder_); AuInt64 startTime = Time::SteadyClockMS(); AuInt64 endTime = startTime + timeout; BOOL status = false; while (!TryLock()) { AuUInt32 timeoutMs = INFINITE; if (timeout != 0) { startTime = Time::SteadyClockMS(); if (startTime >= endTime) { goto exitWin32; } timeoutMs = endTime - startTime; } status = SleepConditionVariableSRW(&this->wakeup_, &this->atomicHolder_, timeoutMs, CONDITION_VARIABLE_LOCKMODE_SHARED); if (!status) { SysAssertExp(GetLastError() == ERROR_TIMEOUT); goto exitWin32; } } returnValue = true; exitWin32: ReleaseSRWLockShared(&this->atomicHolder_); return returnValue; } void Mutex::Unlock() { AcquireSRWLockExclusive(&this->atomicHolder_); this->state_ = 0; ReleaseSRWLockExclusive(&this->atomicHolder_); WakeAllConditionVariable(&this->wakeup_); } AUKN_SYM IWaitable *MutexNew() { return _new Mutex(); } AUKN_SYM void MutexRelease(IWaitable *pMutex) { AuSafeDelete(pMutex); } } #endif