From b73c20d616ac9de9bcfb56ca0df41cb0ead14369 Mon Sep 17 00:00:00 2001 From: J Reece Wilson Date: Tue, 6 Aug 2024 03:22:00 +0100 Subject: [PATCH] [*] Linux: possible regressions in 57c55151733bd3876a9655dce84984163b72be2d. Fixes read while transaction is signaled loops --- Source/IO/FS/Async.Linux.cpp | 8 ++++ Source/IO/UNIX/IOSubmit.Linux.cpp | 77 +++++++++++++++++++------------ 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/Source/IO/FS/Async.Linux.cpp b/Source/IO/FS/Async.Linux.cpp index 97d8c57d..482e2dda 100644 --- a/Source/IO/FS/Async.Linux.cpp +++ b/Source/IO/FS/Async.Linux.cpp @@ -84,7 +84,15 @@ namespace Aurora::IO::FS auto lock = caller_.lock(); return lock->Complete(); } + + UNIX::LinuxOverlappedYield(); + if (LSEvent::IsSignaled()) + { + auto lock = caller_.lock(); + return lock->Complete(); + } + return false; } diff --git a/Source/IO/UNIX/IOSubmit.Linux.cpp b/Source/IO/UNIX/IOSubmit.Linux.cpp index bb7b38f8..e3c9d8a9 100644 --- a/Source/IO/UNIX/IOSubmit.Linux.cpp +++ b/Source/IO/UNIX/IOSubmit.Linux.cpp @@ -645,7 +645,8 @@ namespace Aurora::IO::UNIX (void)LinuxOverlappedTrySubmitWork(); } - } while (timeout || AuExchange(bAgain, false)); + } + while (timeout || AuExchange(bAgain, false)); return dwApcsSent; } @@ -698,9 +699,18 @@ namespace Aurora::IO::UNIX iocb * ptr = &pollSubmit; iocb ** ptrArray = &ptr; - errno = 0; - + bool bEpollTriggered {}; + io_event ioEvents[1024]; + AuTuple toProcess[1024] {}; + int toProcessDone {}; + int temp {}; + bool bAgain {}; int error; + + redo: + toProcessDone = 0; + bEpollTriggered = false; + do { error = io_submit(io->context, 1, ptrArray); @@ -715,18 +725,11 @@ namespace Aurora::IO::UNIX { SysPushErrorIO(); return -1; - } - - bool bEpollTriggered {}; - io_event ioEvents[1024]; - AuTuple toProcess[1024] {}; - int toProcessDone {}; - int temp {}; - bool bAgain {}; + }; do { - if (timeout) + if (timeout && !bAgain) { AuUInt64 uTimeNow = AuTime::SteadyClockNS(); if (uTargetTime <= uTimeNow) @@ -800,16 +803,12 @@ namespace Aurora::IO::UNIX SysPanic("io_getevents() is not implemented on this architecture."); } } - - bAgain = AuExchange(io->bPollHit, false); - - if (bAgain) - { - (void)LinuxOverlappedTrySubmitWork(); - } - } while ((timeout ? !bEpollTriggered : false) || AuExchange(bAgain, false)); + } + while ((timeout ? !bEpollTriggered : false)); exit: + bAgain = false; + io_event finalEpollEvent {}; if (!bEpollTriggered) { @@ -838,6 +837,12 @@ namespace Aurora::IO::UNIX handle->LIOS_SendProcess(bytesTransacted, bError, errNo); } + if ((bAgain = AuExchange(io->bPollHit, false))) + { + (void)LinuxOverlappedTrySubmitWork(); + goto redo; + } + if (bEpollTriggered) { return epoll_wait(epfd, events, maxevents, 0); @@ -855,7 +860,16 @@ namespace Aurora::IO::UNIX bool LinuxOverlappedWaitForOne(AuUInt32 timeout, AuUInt read, AuUInt write, bool &bReadTriggered, bool &bWriteTriggered) { timespec targetTime; + iocb submit {}; + iocb readSubmit {}; + iocb writeSubmit {}; bool bRet { true }; + io_event ioEvents[1024]; + AuTuple toProcess[1024] {}; + int toProcessDone {}; + int temp; + bool bTryAgain {}; + auto io = GetTls(); bWriteTriggered = false; @@ -886,9 +900,6 @@ namespace Aurora::IO::UNIX return false; } - iocb submit {}; - iocb readSubmit {}; - iocb writeSubmit {}; AuMemset(&readSubmit, 0, sizeof(readSubmit)); AuMemset(&writeSubmit, 0, sizeof(readSubmit)); AuMemset(&submit, 0, sizeof(submit)); @@ -915,6 +926,8 @@ namespace Aurora::IO::UNIX ptrArray[iocbIdx++] = &writeSubmit; } + redo: + toProcessDone = 0; int error; do { @@ -933,14 +946,9 @@ namespace Aurora::IO::UNIX return -1; } - io_event ioEvents[1024]; - AuTuple toProcess[1024] {}; - int toProcessDone {}; - int temp; - do { - if (timeout) + if (timeout && !bTryAgain) { AuUInt64 uTimeNow = AuTime::SteadyClockNS(); if (uTargetTime <= uTimeNow) @@ -1025,9 +1033,12 @@ namespace Aurora::IO::UNIX } } - } while (timeout ? (!bReadTriggered && !bWriteTriggered) : false); + } + while (timeout ? (!bReadTriggered && !bWriteTriggered) : false); exit: + bTryAgain = false; + for (int i = 0; i < iocbIdx; i++) { io_event finalEpollEvent {}; @@ -1071,6 +1082,12 @@ namespace Aurora::IO::UNIX handle->LIOS_SendProcess(bytesTransacted, bError, errNo); } + if ((bTryAgain = AuExchange(io->bPollHit, false))) + { + (void)LinuxOverlappedTrySubmitWork(); + goto redo; + } + return bRet; }