/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: Mutex.Win32.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "Mutex.Generic.hpp" #if !defined(_AURUNTIME_GENERICMUTEX) #include "Mutex.NT.hpp" namespace Aurora::Threading::Primitives { Mutex::Mutex() { InitializeSRWLock(&atomicHolder_); InitializeConditionVariable(&wakeup_); state_ = 0; } Mutex::~Mutex() { } bool Mutex::HasOSHandle(AuMach &mach) { return false; } bool Mutex::TryLock() { return _interlockedbittestandset(&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(&atomicHolder_); AuInt64 startTime = Time::CurrentClockMS(); AuInt64 endTime = startTime + timeout; BOOL status = false; while (!TryLock()) { AuUInt32 timeoutMs = INFINITE; if (timeout != 0) { timeoutMs = endTime - static_cast(Time::CurrentClockMS()); if (timeoutMs < 0) { goto exitWin32; } } status = SleepConditionVariableSRW(&wakeup_, &atomicHolder_, endTime, CONDITION_VARIABLE_LOCKMODE_SHARED); if (!status) { SysAssertExp(GetLastError() == ERROR_TIMEOUT); goto exitWin32; } } exitWin32: returnValue = true; ReleaseSRWLockShared(&atomicHolder_); return returnValue; } void Mutex::Unlock() { AcquireSRWLockExclusive(&atomicHolder_); state_ = 0; ReleaseSRWLockExclusive(&atomicHolder_); WakeAllConditionVariable(&wakeup_); } AUKN_SYM IWaitable *MutexNew() { return _new Mutex(); } AUKN_SYM void MutexRelease(IWaitable *waitable) { SafeDelete(waitable); } } #endif