/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: RWLock.hpp Date: 2021-6-9 Author: Reece ***/ #pragma once namespace Aurora::Threading::Primitives { struct IRWLock { /** * @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. 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; /** * @brief Allows for read-to-write upgrades when the decision to esclate is made based upon a shared resource * which would be lost by unlocking and relocking in exclusive mode. * 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() 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() holder reentrancy, and allows AsReadable() holder entrancy as AsWritable() lock AUKN_SHARED_SOO_NCM(RWRenterableLock, IRWLock, kPrimitiveSizeRWLock); }