/*** Copyright (C) 2021-2024 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuCriticalSection.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "AuCriticalSection.hpp" namespace Aurora::Threading::Primitives { CriticalSectionImpl::CriticalSectionImpl() { this->owner_ = {}; this->count_ = 0; } CriticalSectionImpl::~CriticalSectionImpl() { } bool CriticalSectionImpl::HasOSHandle(AuMach &mach) { return false; } bool CriticalSectionImpl::TryLock() { auto cur = GetThreadCookie(); if (this->owner_ == cur) { this->count_++; return true; } if (!this->mutex_.TryLock()) { return false; } this->owner_ = cur; this->count_ = 1; return true; } void CriticalSectionImpl::Lock() { auto status = LockMS(0); SysAssert(status, "Spurious critical section wakeup"); } bool CriticalSectionImpl::LockMS(AuUInt64 timeout) { auto cur = GetThreadCookie(); if (this->owner_ == cur) { this->count_++; return true; } if (!this->mutex_.LockMS(timeout)) { return false; } this->owner_ = cur; this->count_ = 1; return true; } bool CriticalSectionImpl::LockNS(AuUInt64 timeout) { auto cur = GetThreadCookie(); if (this->owner_ == cur) { this->count_++; return true; } if (!this->mutex_.LockNS(timeout)) { return false; } this->owner_ = cur; this->count_ = 1; return true; } bool CriticalSectionImpl::LockAbsNS(AuUInt64 timeout) { auto cur = GetThreadCookie(); if (this->owner_ == cur) { this->count_++; return true; } if (!this->mutex_.LockAbsNS(timeout)) { return false; } this->owner_ = cur; this->count_ = 1; return true; } bool CriticalSectionImpl::LockAbsMS(AuUInt64 timeout) { auto cur = GetThreadCookie(); if (this->owner_ == cur) { this->count_++; return true; } if (!this->mutex_.LockAbsMS(timeout)) { return false; } this->owner_ = cur; this->count_ = 1; return true; } void CriticalSectionImpl::Unlock() { if (--this->count_ == 0) { this->owner_ = {}; this->mutex_.Unlock(); } } bool CriticalSectionImpl::HasLockImplementation() { return true; } AUKN_SYM IWaitable *CriticalSectionNew() { return _new CriticalSectionImpl(); } AUKN_SYM void CriticalSectionRelease(IWaitable *pCriticalSection) { AuSafeDelete(pCriticalSection); } AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, CriticalSection, CriticalSectionImpl) }