From 56681889458e2c8dec6dce10fe0d5df7cda44059 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Sun, 31 Mar 2024 09:26:56 +0100 Subject: [PATCH] [*] Harden IO handle interface --- Source/IO/AuIOHandle.cpp | 18 ++++++++++++++- Source/IO/AuIOHandle.hpp | 48 +++++++++++++++++++++++++++++++--------- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/Source/IO/AuIOHandle.cpp b/Source/IO/AuIOHandle.cpp index f9580bdc..8c88aea4 100644 --- a/Source/IO/AuIOHandle.cpp +++ b/Source/IO/AuIOHandle.cpp @@ -61,6 +61,8 @@ namespace Aurora::IO { SysCheckArgNotNull(pHandle, false); + AU_LOCK_GUARD(this); + auto pSrc = AuStaticCast(pHandle); auto pDest = this; @@ -79,6 +81,8 @@ namespace Aurora::IO bool AFileHandle::InitFromCopy(AuUInt64 uOSHandle) { + AU_LOCK_GUARD(this); + if (this->IsValid()) { return false; @@ -99,6 +103,8 @@ namespace Aurora::IO bool AFileHandle::InitFromMove(AuUInt64 uOSHandle) { + AU_LOCK_GUARD(this); + if (this->IsValid()) { return false; @@ -113,6 +119,8 @@ namespace Aurora::IO bool AFileHandle::InitFromPair(AuOptional optOSReadHandle, AuOptional optOSWriteHandle) { + AU_LOCK_GUARD(this); + if (this->IsValid()) { return false; @@ -152,6 +160,8 @@ namespace Aurora::IO bool AFileHandle::InitFromPairMove(AuOptional uOSReadHandle, AuOptional uOSWriteHandle) { + AU_LOCK_GUARD(this); + if (this->IsValid()) { return false; @@ -166,6 +176,8 @@ namespace Aurora::IO bool AFileHandle::InitFromStreamEnum(EStandardStream eStream) { + AU_LOCK_GUARD(this); + switch (eStream) { case EStandardStream::eInputStream: @@ -349,6 +361,8 @@ namespace Aurora::IO bool AFileHandle::InitFromSharing(const AuString &handle) { + AU_LOCK_GUARD(this); + if (this->uOSReadHandle || this->uOSWriteHandle) { @@ -392,7 +406,9 @@ namespace Aurora::IO } AuString AFileHandle::SharingGetString() - { + { + AU_LOCK_GUARD(this); + AuString handle; if (this->pIPCString) diff --git a/Source/IO/AuIOHandle.hpp b/Source/IO/AuIOHandle.hpp index 40a73e21..c92e6402 100644 --- a/Source/IO/AuIOHandle.hpp +++ b/Source/IO/AuIOHandle.hpp @@ -88,17 +88,43 @@ namespace Aurora::IO bool ShouldClone(); - AuOptional uOSWriteHandle; - AuOptional uOSReadHandle; - AuSPtr pThat; - AuString path; - IPC::IPCPipeImpl *pIPCPipe {}; - mutable AuOptional optIsFile; - mutable AuOptional optIsPipe; - mutable AuOptional optIsTTY; - mutable AuSPtr pIPCString; - AuUInt uThreadId {}; - bool bIsAsync {}, bFlushOnClose {}, bShouldWriteEoS {}, bDirectIO {}; + std::shared_ptr pThat; + AuString path; + IPC::IPCPipeImpl * pIPCPipe { }; + mutable AuSPtr pIPCString; + AuUInt uThreadId { }; + AuOptional uOSWriteHandle; + AuOptional uOSReadHandle; + mutable AuOptional optIsFile; + mutable AuOptional optIsPipe; + mutable AuOptional optIsTTY; + AuUInt8 bShouldWriteEoS : 1 { 0 }; + AuUInt8 bFlushOnClose : 1 { 0 }; + AuUInt8 bDirectIO : 1 { 0 }; + AuUInt8 bIsAsync : 1 { 0 }; + AuAUInt32 uLock { 0 }; + + inline void Lock() + { + if (!AuAtomicTestAndSet(&this->uLock, 0)) + { + return; + } + + { + AuUInt32 uOld {}; + while ((uOld = AuAtomicCompareExchange(&this->uLock, 1u, 0u)) != 0u) + { + AuThreading::WaitOnAddress((const void *)&this->uLock, &uOld, 4, 0, true); + } + } + } + + inline void Unlock() + { + AuAtomicClearU8Lock(&this->uLock); + AuThreading::WakeOnAddress((const void *)&this->uLock); + } protected: // Implement me: