diff --git a/Include/Aurora/IO/Adapters/IOAdapterAsyncDelegators.hpp b/Include/Aurora/IO/Adapters/IOAdapterAsyncDelegators.hpp index 6a664523..929e1772 100644 --- a/Include/Aurora/IO/Adapters/IOAdapterAsyncDelegators.hpp +++ b/Include/Aurora/IO/Adapters/IOAdapterAsyncDelegators.hpp @@ -13,4 +13,7 @@ namespace Aurora::IO::Adapters AUKN_SYM AuSPtr NewAsyncTransactionFromStreamSeekingReader(const AuSPtr &pStreamReader, AuOptional workers); AUKN_SYM AuSPtr NewAsyncTransactionFromStreamWriter(const AuSPtr &pStreamWriter, AuOptional workers); AUKN_SYM AuSPtr NewAsyncTransactionFromStreamSeekingWriter(const AuSPtr &pStreamWriter, AuOptional workers); + AUKN_SYM AuSPtr NewAsyncTransactionFromStreamSeekingPair(const AuSPtr &pStreamReader, + const AuSPtr &pStreamWriter, + AuOptional workers); } \ No newline at end of file diff --git a/Include/Aurora/IO/FS/IMemoryMappedFile.hpp b/Include/Aurora/IO/FS/IMemoryMappedFile.hpp index 7c0e535d..0a6fcd9f 100644 --- a/Include/Aurora/IO/FS/IMemoryMappedFile.hpp +++ b/Include/Aurora/IO/FS/IMemoryMappedFile.hpp @@ -11,6 +11,7 @@ namespace Aurora::IO::FS { struct IMemoryMappedFile { + virtual IAsyncFileStream * ToAsyncFile() = 0; virtual IIOHandle * ToHandle() = 0; virtual AuUInt GetBaseAddress() = 0; @@ -22,6 +23,7 @@ namespace Aurora::IO::FS virtual AuSPtr NewAsyncReadTransaction() = 0; virtual AuSPtr NewAsyncWriteTransaction() = 0; + virtual AuSPtr NewAsyncAnyTransaction() = 0; virtual ISeekingReader * ToStreamSeekingReader() = 0; virtual ISeekingWriter * ToStreamSeekingWriter() = 0; @@ -32,5 +34,6 @@ namespace Aurora::IO::FS virtual void Prefetch(AuUInt uOffset, AuUInt uLength) = 0; + AURT_ADD_USR_DATA_EXP(this->ToAsyncFile()); }; } \ No newline at end of file diff --git a/Source/IO/Adapters/AuIOAdapterAsyncDelegators.cpp b/Source/IO/Adapters/AuIOAdapterAsyncDelegators.cpp index 8f94c14c..ae219802 100644 --- a/Source/IO/Adapters/AuIOAdapterAsyncDelegators.cpp +++ b/Source/IO/Adapters/AuIOAdapterAsyncDelegators.cpp @@ -253,4 +253,18 @@ namespace Aurora::IO::Adapters pObject->workers = workers.ValueOr(GetAuxWorkerPool()); return pObject; } + + AUKN_SYM AuSPtr NewAsyncTransactionFromStreamSeekingPair(const AuSPtr &pStreamReader, + const AuSPtr &pStreamWriter, + AuOptional workers) + { + SysCheckArgNotNull(pStreamWriter, {}); + SysCheckArgNotNull(pStreamReader, {}); + auto pObject = AuMakeShared(); + SysCheckNotNullMemory(pObject, {}); + pObject->pStreamReaderEx = pStreamReader; + pObject->pStreamWriterEx = pStreamWriter; + pObject->workers = workers.ValueOr(GetAuxWorkerPool()); + return pObject; + } } \ No newline at end of file diff --git a/Source/IO/FS/FSMemoryMappedFile.cpp b/Source/IO/FS/FSMemoryMappedFile.cpp index 53077c16..3e0d1ae8 100644 --- a/Source/IO/FS/FSMemoryMappedFile.cpp +++ b/Source/IO/FS/FSMemoryMappedFile.cpp @@ -58,34 +58,85 @@ namespace Aurora::IO::FS return AuMakeShared(this->ToWriteView(), this->pView); } + void MemoryMappedFile::InitTransactions() + { + if (AuThreading::InitOnceLocker::TryLock(&this->initOnce)) + { + bool bOk { true }; + + if (this->eMode == EFileOpenMode::eReadWrite || + this->eMode == EFileOpenMode::eRead) + { + auto pReader = AuMakeShared(this->ToReadViewAlt(), this->pView); + + if (pReader) + { + auto iBaseOffset = 0 - + AuInt64(this->uFileMapOffset) + + this->iAdjustStreamOffset; + + pReader->GetBaseOffset() = iBaseOffset; + } + else + { + bOk = false; + } + + this->pStreamReader = pReader; + } + + if (this->eMode == EFileOpenMode::eReadWrite || + this->eMode == EFileOpenMode::eWrite) + { + auto pWriter = AuMakeShared(this->ToWriteViewAlt(), this->pView); + + if (pWriter) + { + auto iBaseOffset = 0 - + AuInt64(this->uFileMapOffset) + + this->iAdjustStreamOffset; + + pWriter->GetBaseOffset() = iBaseOffset; + } + else + { + bOk = false; + } + + this->pStreamWriter = pWriter; + } + AuThreading::InitOnceLocker::Finish(&this->initOnce, !bOk); + } + else + { + this->initOnce.Wait(); + } + } + AuSPtr MemoryMappedFile::NewAsyncReadTransaction() { - auto pReader = AuMakeShared(this->ToReadViewAlt(), this->pView); - SysCheckNotNullMemory(pReader, {}); - - auto iBaseOffset = 0 - - AuInt64(this->uFileMapOffset) + - this->iAdjustStreamOffset; - - pReader->GetBaseOffset() = iBaseOffset; - - auto pTransaction = Adapters::NewAsyncTransactionFromStreamSeekingReader(pReader, {}); + this->InitTransactions(); + SysCheckNotNullMemory(this->pStreamReader, {}); + auto pTransaction = Adapters::NewAsyncTransactionFromStreamSeekingReader(this->pStreamReader, {}); SysCheckNotNullMemory(pTransaction, {}); return pTransaction; } AuSPtr MemoryMappedFile::NewAsyncWriteTransaction() { - auto pWriter = AuMakeShared(this->ToWriteViewAlt(), this->pView); - SysCheckNotNullMemory(pWriter, {}); + this->InitTransactions(); + SysCheckNotNullMemory(this->pStreamWriter, {}); + auto pTransaction = Adapters::NewAsyncTransactionFromStreamSeekingWriter(this->pStreamWriter, {}); + SysCheckNotNullMemory(pTransaction, {}); + return pTransaction; + } - auto iBaseOffset = 0 - - AuInt64(this->uFileMapOffset) + - this->iAdjustStreamOffset; - - pWriter->GetBaseOffset() = iBaseOffset; - - auto pTransaction = Adapters::NewAsyncTransactionFromStreamSeekingWriter(pWriter, {}); + AuSPtr MemoryMappedFile::NewAsyncAnyTransaction() + { + this->InitTransactions(); + SysCheckNotNullMemory(this->pStreamWriter, {}); + SysCheckNotNullMemory(this->pStreamReader, {}); + auto pTransaction = Adapters::NewAsyncTransactionFromStreamSeekingPair(this->pStreamReader, this->pStreamWriter, {}); SysCheckNotNullMemory(pTransaction, {}); return pTransaction; } @@ -200,6 +251,35 @@ namespace Aurora::IO::FS }); } + IAsyncFileStream *MemoryMappedFile::ToAsyncFile() + { + return this; + } + + AuSPtr MemoryMappedFile::NewTransaction() + { + return this->NewAsyncAnyTransaction(); + } + + bool MemoryMappedFile::BlockingTruncate(AuUInt64 length) + { + return false; + } + + bool MemoryMappedFile::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters) + { + this->InitTransactions(); + SysCheckNotNullMemory(this->pStreamReader, {}); + return this->pStreamReader->ArbitraryRead(offset, parameters) == EStreamError::eErrorNone; + } + + bool MemoryMappedFile::BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead ¶meters) + { + this->InitTransactions(); + SysCheckNotNullMemory(this->pStreamWriter, {}); + return this->pStreamWriter->ArbitraryWrite(offset, parameters) == EStreamError::eErrorNone; + } + bool MemoryMappedFile::Init(EFileOpenMode eMode, AuUInt64 uFileMapOffset, AuUInt64 uFileMapLength, @@ -213,7 +293,7 @@ namespace Aurora::IO::FS uFileMapLength = pHandle->GetFileLength(); } - + this->eMode = eMode; this->uFileMapLength = uFileMapLength; this->uFileMapOffset = uFileMapOffset; this->iAdjustStreamOffset = iAdjustStreamOffset; diff --git a/Source/IO/FS/FSMemoryMappedFile.hpp b/Source/IO/FS/FSMemoryMappedFile.hpp index 768fe0c9..8b1d6554 100644 --- a/Source/IO/FS/FSMemoryMappedFile.hpp +++ b/Source/IO/FS/FSMemoryMappedFile.hpp @@ -9,9 +9,10 @@ namespace Aurora::IO::FS { - struct MemoryMappedFile : IMemoryMappedFile + struct MemoryMappedFile : IMemoryMappedFile, IAsyncFileStream { virtual IIOHandle * ToHandle() override; + virtual IAsyncFileStream * ToAsyncFile() override; virtual AuUInt GetBaseAddress() override; virtual AuUInt GetEndAddress() override; @@ -20,8 +21,11 @@ namespace Aurora::IO::FS virtual AuSPtr NewStreamReader() override; virtual AuSPtr NewStreamWriter() override; + void InitTransactions(); + virtual AuSPtr NewAsyncReadTransaction() override; virtual AuSPtr NewAsyncWriteTransaction() override; + virtual AuSPtr NewAsyncAnyTransaction() override; virtual ISeekingReader * ToStreamSeekingReader() override; virtual ISeekingWriter * ToStreamSeekingWriter() override; @@ -36,6 +40,13 @@ namespace Aurora::IO::FS virtual void Prefetch(AuUInt uOffset, AuUInt uLength) override; + + AuSPtr NewTransaction() override; + + bool BlockingTruncate(AuUInt64 length) override; + bool BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters) override; + bool BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead ¶meters) override; + bool Init(EFileOpenMode eMode, AuUInt64 uFileMapOffset, AuUInt64 uFileMapLength, @@ -46,9 +57,13 @@ namespace Aurora::IO::FS AuSPtr pHandleShared; AuSPtr pView; AuUInt64 uFileMapLength; + EFileOpenMode eMode; AuUInt64 uFileMapOffset; AuInt64 iAdjustStreamOffset; AuOptional optSeekableWriter; AuOptional optSeekableReader; + AuInitOnce initOnce; + AuSPtr pStreamReader; + AuSPtr pStreamWriter; }; } \ No newline at end of file