diff --git a/Source/IO/FS/Async.NT.cpp b/Source/IO/FS/Async.NT.cpp index de215494..062bfd51 100644 --- a/Source/IO/FS/Async.NT.cpp +++ b/Source/IO/FS/Async.NT.cpp @@ -226,8 +226,16 @@ namespace Aurora::IO::FS bool NtAsyncFileTransaction::Init(const AuSPtr &handle) { this->pHandle_ = handle; + // TODO: runtime config + #if 0 + if (gRuntimeConfig.fio.) this->overlap.hEvent = this->event = CreateEventW(nullptr, true, false, nullptr); return this->overlap.hEvent != INVALID_HANDLE_VALUE; + #else + + this->bLazyInitLater = true; + return true; + #endif } void NtAsyncFileTransaction::ResetAIO() @@ -331,14 +339,45 @@ namespace Aurora::IO::FS return true; } + bool NtAsyncFileTransaction::LazyLoad() + { + if (this->event && this->event != INVALID_HANDLE_VALUE) + { + return true; + } + + if (this->bLazyInitLater) + { + this->overlap.hEvent = this->event = CreateEventW(nullptr, true, false, nullptr); + if (this->overlap.hEvent == INVALID_HANDLE_VALUE) + { + return false; + } + + this->bLazyInitLater = false; + return true; + } + else + { + return true; + } + } + bool NtAsyncFileTransaction::StartRead(AuUInt64 offset, const AuMemoryViewWrite &memoryView) { + AU_LOCK_GUARD(this->sectionLock); + if (this->isIrredeemable_) { SysPushErrorIO("Transaction was signaled to be destroyed to reset mid synchronizable operation. You can no longer use this stream object"); return false; } + if (!LazyLoad()) + { + return false; + } + if (!IDontWannaUsePorts()) { return false; @@ -394,12 +433,19 @@ namespace Aurora::IO::FS bool NtAsyncFileTransaction::StartWrite(AuUInt64 offset, const AuMemoryViewRead &memoryView) { + AU_LOCK_GUARD(this->sectionLock); + if (this->isIrredeemable_) { SysPushErrorIO("Transaction was signaled to be destroyed to reset mid synchronizable operation. You can no longer use this stream object"); return false; } + if (!LazyLoad()) + { + return false; + } + if (!IDontWannaUsePorts()) { return false; @@ -512,6 +558,8 @@ namespace Aurora::IO::FS void NtAsyncFileTransaction::Reset() { + AU_LOCK_GUARD(this->sectionLock); + if (this->dwLastAbstractStat) { this->isIrredeemable_ = true; @@ -552,6 +600,8 @@ namespace Aurora::IO::FS bool NtAsyncFileTransaction::TryAttachToCompletionGroup(const AuSPtr &pCompletionGroup) { + AU_LOCK_GUARD(this->sectionLock); + if (!this->bOwnsEvent_ || !pCompletionGroup) { @@ -565,6 +615,7 @@ namespace Aurora::IO::FS } this->bOwnsEvent_ = false; + this->bLazyInitLater = false; AuWin32CloseHandle(this->event); this->event = this->overlap.hEvent = (HANDLE)AuStaticCast(pLoopSource)->GetHandle(); pCompletionGroup->AddWorkItem(this->SharedFromThis()); @@ -650,6 +701,7 @@ namespace Aurora::IO::FS bool NtAsyncFileTransaction::Complete() { + AU_LOCK_GUARD(this->sectionLock); return CompleteEx(false); } @@ -720,6 +772,11 @@ namespace Aurora::IO::FS { if (this->bOwnsEvent_) { + if (!this->LazyLoad()) + { + return {}; + } + SysCheckRetExpNotNullMemory(AuMakeShared(AuSharedFromThis()), {}); } else if (this->pCompletionGroup_) diff --git a/Source/IO/FS/Async.NT.hpp b/Source/IO/FS/Async.NT.hpp index ac3b4ef8..c4d5944c 100644 --- a/Source/IO/FS/Async.NT.hpp +++ b/Source/IO/FS/Async.NT.hpp @@ -42,6 +42,8 @@ namespace Aurora::IO::FS bool InitWeak(const AuSPtr &handle); void ResetAIO(); + bool LazyLoad(); + bool StartRead(AuUInt64 offset, const AuMemoryViewWrite &memoryView) override; bool StartWrite(AuUInt64 offset, const AuMemoryViewRead &memoryView) override; @@ -92,6 +94,7 @@ namespace Aurora::IO::FS AuUInt32 dwLastAbstractStat {}; AuUInt64 qwLastAbstractOffset {}; bool bLatch {}; + bool bLazyInitLater {}; AuUInt32 dwLastBytes {}; AuUInt32 dwOsErrorCode {}; bool bHasFailed {}; @@ -100,7 +103,7 @@ namespace Aurora::IO::FS AuWPtr pNtIpcPipeImpl; AuMemoryViewRead readView; AuMemoryViewWrite writeView; - + AuCriticalSection sectionLock; private: AuSPtr pHandle_; AuWPtr wpHandle_;