/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuIOHandle.hpp Date: 2023-7-28 Author: Reece ***/ #pragma once namespace Aurora::IO::IPC { struct IPCPipeImpl; } namespace Aurora::IO { struct AFileHandle : IIOHandle { AFileHandle(); ~AFileHandle(); bool InitFromHandle(const AuSPtr &pHandle) override; bool InitFromCopy(AuUInt64 uOSHandle) override; bool InitFromMove(AuUInt64 uOSHandle) override; bool InitFromPair(AuOptional uOSReadHandle, AuOptional uOSWriteHandle) override; bool InitFromPairMove(AuOptional uOSReadHandle, AuOptional uOSWriteHandle) override; bool InitFromStreamEnum(EStandardStream eStream) override; bool InitFromHandleCopy(const IIOHandle *pHandle) override; bool InitFromSharing(const AuROString &handle) override; bool InitFromPath(HandleCreate create) override; AuUInt64 GetOSHandle() const override; AuOptional GetOSHandleSafe() const override; AuUInt64 GetOSReadHandle() const override; AuOptional GetOSReadHandleSafe() const override; AuUInt64 GetOSWriteHandle() const override; AuOptional GetOSWriteHandleSafe() const override; bool IsValid() const override; bool HasUniqueWriteHandle()const override; bool IsAsync() const override; const AuString &GetPath() const override; bool IsFile() const override; bool IsTTY() const override; bool IsPipe() const override; bool IsFlushOnClose() const override; void SetFlushOnClose(bool bFlushOnClose) override; bool IsWriteEoSOnClose() const override; void SetWriteEoSOnClose(bool bShouldWriteEoS) override; void InitStdIn(bool bSharing = false); void InitStdOut(bool bError = false, bool bSharing = false); bool SectionLock(AuUInt64 uOffset, AuUInt64 uLength, FS::EFileAdvisoryLockLevel level) override; bool SectionUnlock(AuUInt64 uOffset, AuUInt64 uLength) override; AuString SharingGetString() override; bool SharingIsShared() override; void SharingStop() override; AuUInt64 GetFileLength() override; bool ShouldClone(); 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; union { struct { AuUInt8 bShouldWriteEoS : 1; AuUInt8 bFlushOnClose : 1; AuUInt8 bDirectIO : 1; AuUInt8 bIsAsync : 1; }; AuUInt8 uFlags {}; }; 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: // bool InitFromPath(HandleCreate create) override; static AuUInt64 DupHandle(AuUInt64 uOSHandle, bool bWriteAccess); static AuUInt64 DupHandle(AuUInt64 uOSHandle, bool bWriteAccess, bool bShareAccess); static void CloseHandle(AuUInt64 uOSHandle, bool bFlushOnClose, bool bWriteEoS); inline void CloseHandle(AuUInt64 uOSHandle) { CloseHandle(uOSHandle, this->bFlushOnClose, false); } }; }