[*] perf/ NT Async FIO: lazy create event objects, like linux, now that we expect every application to use completion groups by default

[*] harden/ NT Async FIO: use a critical section to avoid abuse from language bindings
This commit is contained in:
Reece Wilson 2024-12-03 20:31:41 +00:00
parent 1af9338301
commit 14ab47f192
2 changed files with 61 additions and 1 deletions

View File

@ -226,8 +226,16 @@ namespace Aurora::IO::FS
bool NtAsyncFileTransaction::Init(const AuSPtr<IIOHandle> &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<CompletionGroup::ICompletionGroup> &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<Loop::LSEvent>(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<NtAsyncFileTransactionLoopSource>(AuSharedFromThis()), {});
}
else if (this->pCompletionGroup_)

View File

@ -42,6 +42,8 @@ namespace Aurora::IO::FS
bool InitWeak(const AuSPtr<IIOHandle> &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<Aurora::IO::IPC::IPCPipeImpl> pNtIpcPipeImpl;
AuMemoryViewRead readView;
AuMemoryViewWrite writeView;
AuCriticalSection sectionLock;
private:
AuSPtr<IIOHandle> pHandle_;
AuWPtr<IIOHandle> wpHandle_;