From 48aa0f01b1c0869c29e0c8f859a00f863a16f37a Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Sat, 9 Mar 2024 00:46:50 +0000 Subject: [PATCH] [+] IFileStream::ToStreamSeekingReader [+] IFileStream::ToStreamSeekingWriter [*] Mitigation for Linshids god awful IO subsystems --- Include/Aurora/IO/FS/IAsyncFileStream.hpp | 1 + Include/Aurora/IO/FS/IFileStream.hpp | 5 +++++ Include/Aurora/IO/IAsyncTransaction.hpp | 1 + Source/IO/AuIOHandle.Unix.cpp | 3 +-- Source/IO/FS/Async.Linux.cpp | 20 ++++++++++++++++++++ Source/IO/FS/Async.Linux.hpp | 1 + Source/IO/FS/FileStream.NT.cpp | 14 +++++++++++++- Source/IO/FS/FileStream.NT.hpp | 4 ++++ Source/IO/FS/FileStream.Unix.cpp | 14 +++++++++++++- Source/IO/FS/FileStream.Unix.hpp | 4 ++++ 10 files changed, 63 insertions(+), 4 deletions(-) diff --git a/Include/Aurora/IO/FS/IAsyncFileStream.hpp b/Include/Aurora/IO/FS/IAsyncFileStream.hpp index e553f44e..83bbef67 100644 --- a/Include/Aurora/IO/FS/IAsyncFileStream.hpp +++ b/Include/Aurora/IO/FS/IAsyncFileStream.hpp @@ -14,6 +14,7 @@ namespace Aurora::IO namespace Aurora::IO::FS { + // Thread-Local! struct IAsyncFileStream { virtual AuSPtr NewTransaction() = 0; diff --git a/Include/Aurora/IO/FS/IFileStream.hpp b/Include/Aurora/IO/FS/IFileStream.hpp index 2a74ff78..c95078c8 100644 --- a/Include/Aurora/IO/FS/IFileStream.hpp +++ b/Include/Aurora/IO/FS/IFileStream.hpp @@ -9,6 +9,7 @@ namespace Aurora::IO::FS { + // Thread-Local! struct IFileStream { /** @@ -103,6 +104,10 @@ namespace Aurora::IO::FS */ virtual IO::IStreamWriter *ToStreamWriter() = 0; + virtual IO::ISeekingReader *ToStreamSeekingReader() = 0; + + virtual IO::ISeekingWriter *ToStreamSeekingWriter() = 0; + AURT_ADD_USR_DATA; }; } \ No newline at end of file diff --git a/Include/Aurora/IO/IAsyncTransaction.hpp b/Include/Aurora/IO/IAsyncTransaction.hpp index 4a156cf1..7b586f00 100644 --- a/Include/Aurora/IO/IAsyncTransaction.hpp +++ b/Include/Aurora/IO/IAsyncTransaction.hpp @@ -29,6 +29,7 @@ namespace Aurora::IO * Do not access this object across threads as there is no MT guarantee on this particular object * Using the synchronization primitives, loop or authreading, is fine. */ + // Thread-Local! struct IAsyncTransaction { virtual bool StartRead(AuUInt64 uOffset, const AuSPtr &memoryView) = 0; diff --git a/Source/IO/AuIOHandle.Unix.cpp b/Source/IO/AuIOHandle.Unix.cpp index 39c424cf..62fa890c 100644 --- a/Source/IO/AuIOHandle.Unix.cpp +++ b/Source/IO/AuIOHandle.Unix.cpp @@ -143,8 +143,7 @@ namespace Aurora::IO return false; } - if (create.bAsyncHandle || - create.bDirectIOMode) + if (create.bDirectIOMode) { this->bDirectIO = true; } diff --git a/Source/IO/FS/Async.Linux.cpp b/Source/IO/FS/Async.Linux.cpp index 4fc7997b..089416a3 100644 --- a/Source/IO/FS/Async.Linux.cpp +++ b/Source/IO/FS/Async.Linux.cpp @@ -139,6 +139,26 @@ namespace Aurora::IO::FS AuSPtr LinuxAsyncFileStream::NewTransaction() { + if (!AuStaticCast(this->pHandle_)->bDirectIO) + { + auto &pFSReader = this->pCache_; + + if (!pFSReader) + { + pFSReader = AuFS::OpenBlockingFileStreamFromHandle(this->pHandle_); + } + + if (!pFSReader) + { + SysPushErrorNested(); + return {}; + } + + auto pStreamReader = AuSharedPointerFromShared(pFSReader->ToStreamSeekingReader(), pFSReader); + auto pStreamWriter = AuSharedPointerFromShared(pFSReader->ToStreamSeekingWriter(), pFSReader); + return Adapters::NewAsyncTransactionFromStreamSeekingPair(pStreamReader, pStreamWriter, {}); + } + auto shared = AuMakeShared(this->pProcessBlock_); if (!shared) { diff --git a/Source/IO/FS/Async.Linux.hpp b/Source/IO/FS/Async.Linux.hpp index afb3c7fc..b78bc925 100644 --- a/Source/IO/FS/Async.Linux.hpp +++ b/Source/IO/FS/Async.Linux.hpp @@ -41,6 +41,7 @@ namespace Aurora::IO::FS private: AuSPtr pProcessBlock_; AuSPtr pHandle_; + AuSPtr pCache_; }; diff --git a/Source/IO/FS/FileStream.NT.cpp b/Source/IO/FS/FileStream.NT.cpp index ffb865c7..3347f1bb 100644 --- a/Source/IO/FS/FileStream.NT.cpp +++ b/Source/IO/FS/FileStream.NT.cpp @@ -18,7 +18,9 @@ namespace Aurora::IO::FS WinFileStream::WinFileStream() : reader_(AuUnsafeRaiiToShared(this)), - writer_(AuUnsafeRaiiToShared(this)) + writer_(AuUnsafeRaiiToShared(this)), + sreader_(AuUnsafeRaiiToShared(this)), + swriter_(AuUnsafeRaiiToShared(this)) { } @@ -484,6 +486,16 @@ namespace Aurora::IO::FS return &this->writer_; } + IO::ISeekingReader *WinFileStream::ToStreamSeekingReader() + { + return &this->sreader_; + } + + IO::ISeekingWriter *WinFileStream::ToStreamSeekingWriter() + { + return &this->swriter_; + } + HANDLE WinFileStream::GetWin32Handle(bool bReadOnly) { if (auto pHandle = this->pHandle_) diff --git a/Source/IO/FS/FileStream.NT.hpp b/Source/IO/FS/FileStream.NT.hpp index ee2026d0..13593ed7 100644 --- a/Source/IO/FS/FileStream.NT.hpp +++ b/Source/IO/FS/FileStream.NT.hpp @@ -34,6 +34,8 @@ namespace Aurora::IO::FS void SetWriteEoSOnClose(bool bFlushOnClose) override; IO::IStreamReader *ToStreamReader() override; IO::IStreamWriter *ToStreamWriter() override; + IO::ISeekingReader *ToStreamSeekingReader() override; + IO::ISeekingWriter *ToStreamSeekingWriter() override; HANDLE GetWin32Handle(bool bReadOnly = false); @@ -43,6 +45,8 @@ namespace Aurora::IO::FS HANDLE hEventHandle_ { INVALID_HANDLE_VALUE }; AuFS::FileReader reader_; AuFS::FileWriter writer_; + AuFS::FileSeekableReader sreader_; + AuFS::FileSeekableWriter swriter_; }; } #endif \ No newline at end of file diff --git a/Source/IO/FS/FileStream.Unix.cpp b/Source/IO/FS/FileStream.Unix.cpp index a3c6d960..19810133 100755 --- a/Source/IO/FS/FileStream.Unix.cpp +++ b/Source/IO/FS/FileStream.Unix.cpp @@ -25,7 +25,9 @@ namespace Aurora::IO::FS PosixFileStream::PosixFileStream() : reader_(AuUnsafeRaiiToShared(this)), - writer_(AuUnsafeRaiiToShared(this)) + writer_(AuUnsafeRaiiToShared(this)), + sreader_(AuUnsafeRaiiToShared(this)), + swriter_(AuUnsafeRaiiToShared(this)) { } @@ -371,6 +373,16 @@ namespace Aurora::IO::FS return &this->writer_; } + IO::ISeekingReader *PosixFileStream::ToStreamSeekingReader() + { + return &this->sreader_; + } + + IO::ISeekingWriter *PosixFileStream::ToStreamSeekingWriter() + { + return &this->swriter_; + } + AUKN_SYM AuSPtr OpenBlockingFileStreamFromHandle(AuSPtr pIOHandle) { auto pStream = AuMakeShared(); diff --git a/Source/IO/FS/FileStream.Unix.hpp b/Source/IO/FS/FileStream.Unix.hpp index 67b8468a..d8fb629f 100644 --- a/Source/IO/FS/FileStream.Unix.hpp +++ b/Source/IO/FS/FileStream.Unix.hpp @@ -35,6 +35,8 @@ namespace Aurora::IO::FS AuSPtr GetHandle() override; IO::IStreamReader *ToStreamReader() override; IO::IStreamWriter *ToStreamWriter() override; + IO::ISeekingReader *ToStreamSeekingReader() override; + IO::ISeekingWriter *ToStreamSeekingWriter() override; int GetUnixHandle(); private: @@ -44,6 +46,8 @@ namespace Aurora::IO::FS bool bMadeTemporary {}, bShouldWriteEoS {}; AuFS::FileReader reader_; AuFS::FileWriter writer_; + AuFS::FileSeekableReader sreader_; + AuFS::FileSeekableWriter swriter_; }; } #endif \ No newline at end of file