[*] Preemptive GetOverlappedResult fast-paths under WaitMultiple2 that rely on the alertable yield under next read/write cannot be trusted if the read count is zero.
Direct IO-specific quirk? Windows 7 specific quirk? Direct IO under Win7 specific quirk? idk, but this fixes it
This commit is contained in:
parent
22c4d25759
commit
30b0c2e0ba
@ -279,6 +279,14 @@ namespace Aurora::IO::FS
|
||||
this->overlap.hEvent = this->event = CreateEventW(nullptr, true, false, nullptr);
|
||||
return this->overlap.hEvent != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
void NtAsyncFileTransaction::ResetAIO()
|
||||
{
|
||||
auto hEvent = this->overlap.hEvent;
|
||||
AuResetMember(this->overlap);
|
||||
this->overlap.hEvent = hEvent;
|
||||
}
|
||||
|
||||
static bool TranslateNtStatus(NtAsyncFileTransaction *that, BOOL val)
|
||||
{
|
||||
auto er = GetLastError();
|
||||
@ -347,12 +355,9 @@ namespace Aurora::IO::FS
|
||||
|
||||
bool NtAsyncFileTransaction::IDontWannaUsePorts()
|
||||
{
|
||||
// TODO: maybe we could use a semaphore counter of read attempts
|
||||
// to allow APC callbacks to drag behind
|
||||
|
||||
if (AuExchange(this->pPin, AuSharedFromThis()))
|
||||
{
|
||||
while (SleepEx(100, true) == WAIT_IO_COMPLETION)
|
||||
while (SleepEx(0, true) == WAIT_IO_COMPLETION)
|
||||
{
|
||||
|
||||
}
|
||||
@ -407,6 +412,7 @@ namespace Aurora::IO::FS
|
||||
this->dwLastAbstractOffset = offset;
|
||||
this->dwLastBytes = 0;
|
||||
|
||||
this->ResetAIO();
|
||||
this->overlap.Offset = AuBitsToLower(offset);
|
||||
this->overlap.OffsetHigh = AuBitsToHigher(offset);
|
||||
|
||||
@ -453,7 +459,8 @@ namespace Aurora::IO::FS
|
||||
this->dwLastBytes = 0;
|
||||
this->dwLastAbstractStat = memoryView->length;
|
||||
this->dwLastAbstractOffset = offset;
|
||||
|
||||
|
||||
this->ResetAIO();
|
||||
this->overlap.Offset = AuBitsToLower(offset);
|
||||
this->overlap.OffsetHigh = AuBitsToHigher(offset);
|
||||
auto ret = ::WriteFileEx(this->pHandle_->writeHandle, memoryView->ptr, memoryView->length, &this->overlap, FileOperationCompletion);
|
||||
@ -533,10 +540,10 @@ namespace Aurora::IO::FS
|
||||
if (::GetOverlappedResult(this->pHandle_->handle,
|
||||
&this->overlap,
|
||||
&read,
|
||||
false))
|
||||
false) && read)
|
||||
{
|
||||
DispatchCb(read);
|
||||
return read;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -51,6 +51,7 @@ namespace Aurora::IO::FS
|
||||
~NtAsyncFileTransaction();
|
||||
|
||||
bool Init(const AuSPtr<FileHandle> &handle);
|
||||
void ResetAIO();
|
||||
|
||||
bool StartRead(AuUInt64 offset, const AuSPtr<AuMemoryViewWrite> &memoryView) override;
|
||||
bool StartWrite(AuUInt64 offset, const AuSPtr<AuMemoryViewRead> &memoryView) override;
|
||||
|
@ -300,10 +300,15 @@ namespace Aurora::IO::Net
|
||||
return true;
|
||||
}
|
||||
|
||||
if (::GetOverlappedResult((HANDLE)this->GetSocket(), &this->overlap, &read, false))
|
||||
if (!this->pMemoryHold)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::GetOverlappedResult((HANDLE)this->GetSocket(), &this->overlap, &read, false) && read)
|
||||
{
|
||||
DispatchCb(read);
|
||||
return read;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -397,7 +402,7 @@ namespace Aurora::IO::Net
|
||||
{
|
||||
if (AuExchange(this->pPin, AuSharedFromThis()))
|
||||
{
|
||||
while (SleepEx(100, true) == WAIT_IO_COMPLETION)
|
||||
while (SleepEx(0, true) == WAIT_IO_COMPLETION)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -52,14 +52,18 @@ namespace Aurora::IO
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
AuDebug::AddMemoryCrunch();
|
||||
|
||||
retTransasctions.reserve(transactions.size());
|
||||
AuTryReserve(retTransasctions, transactions.size());
|
||||
|
||||
for (const auto &file : transactions)
|
||||
{
|
||||
AuTryInsert(handles, AuStaticPointerCast<FS::NtAsyncFileTransaction>(file)->GetHandle());
|
||||
SysAssert(AuTryInsert(handles, AuStaticPointerCast<FS::NtAsyncFileTransaction>(file)->GetHandle()));
|
||||
}
|
||||
|
||||
AuDebug::DecMemoryCrunch();
|
||||
|
||||
auto ret = WaitForMultipleObjectsEx(handles.size(), handles.data(), false, timeoutMs ? timeoutMs : INFINITE, TRUE);
|
||||
|
||||
if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED)
|
||||
@ -71,7 +75,9 @@ namespace Aurora::IO
|
||||
{
|
||||
if (AuStaticPointerCast<FS::NtAsyncFileTransaction>(file)->Complete())
|
||||
{
|
||||
AuTryInsert(retTransasctions, file);
|
||||
AuDebug::AddMemoryCrunch();
|
||||
SysAssert(AuTryInsert(retTransasctions, file));
|
||||
AuDebug::DecMemoryCrunch();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user