diff --git a/Include/Aurora/Threading/Primitives/RWLock.hpp b/Include/Aurora/Threading/Primitives/RWLock.hpp index 511b32d4..07814726 100644 --- a/Include/Aurora/Threading/Primitives/RWLock.hpp +++ b/Include/Aurora/Threading/Primitives/RWLock.hpp @@ -13,16 +13,17 @@ namespace Aurora::Threading::Primitives { /** * @brief Returns a complete IWaitable interface for reantrant access to the protected resources. - * Once a thread takes exclusive access of the resource, only it shall pass read + * Once a thread takes exclusive access of the resource, only it shall pass read. Noting this + * is critical section behaviour, not mutex behaviour. * @return - */ + */ virtual IWaitable *AsReadable() = 0; /** * @brief Returns a complete IWaitable interface for exclusive thread access to the protected resources * * @return - */ + */ virtual IWaitable *AsWritable() = 0; /** @@ -31,20 +32,27 @@ namespace Aurora::Threading::Primitives * You must be careful to consider how this is used to prevent dead-locks * @param timeout in relative nanoseconds * @return - */ + */ virtual bool UpgradeReadToWrite(AuUInt64 timeout) = 0; /** * @brief Reverses UpgradeReadToWrite. * @return - */ + */ virtual bool DowngradeWriteToRead() = 0; + + /** + * @brief Checks if the current thread has acquired a critical-section lock on the mutually exclusive resource + * @return + */ + virtual bool CheckSelfThreadIsWriter() = 0; }; - /// Allows AsReadable entrancy as AsWritable lock + /// Allows AsReadable() holder entrancy as AsWritable() lock + /// Check CheckSelfThreadIsWriter() before any lock guards, if non-reentrant mutual exclusion is desired. AUKN_SHARED_SOO_NCM(RWLock, IRWLock, kPrimitiveSizeRWLock); - /// Allows AsWritable reentrancy, and allows AsReadable entrancy as AsWritable lock + /// Allows AsWritable() holder reentrancy, and allows AsReadable() holder entrancy as AsWritable() lock AUKN_SHARED_SOO_NCM(RWRenterableLock, IRWLock, kPrimitiveSizeRWLock); } \ No newline at end of file diff --git a/Source/Threading/Primitives/AuRWLock.cpp b/Source/Threading/Primitives/AuRWLock.cpp index fa2d267a..f0650408 100644 --- a/Source/Threading/Primitives/AuRWLock.cpp +++ b/Source/Threading/Primitives/AuRWLock.cpp @@ -934,6 +934,13 @@ namespace Aurora::Threading::Primitives return &this->write_; } + + template + bool RWLockImpl::CheckSelfThreadIsWriter() + { + return this->reentrantWriteLockHandle_ == GetThreadCookie(); + } + AUKN_SYM IRWLock *RWLockNew() { return _new RWLockImpl(); diff --git a/Source/Threading/Primitives/AuRWLock.hpp b/Source/Threading/Primitives/AuRWLock.hpp index da803b2c..47b3996e 100644 --- a/Source/Threading/Primitives/AuRWLock.hpp +++ b/Source/Threading/Primitives/AuRWLock.hpp @@ -90,6 +90,8 @@ namespace Aurora::Threading::Primitives IWaitable *AsReadable() override; IWaitable *AsWritable() override; + bool CheckSelfThreadIsWriter() override; + auline ConditionVariableInternal &GetCondition(); auline ConditionVariableInternal &GetConditionWriter();