[*] Linux: possible regressions in 57c5515173. Fixes read while transaction is signaled loops

This commit is contained in:
Reece Wilson 2024-08-06 03:22:00 +01:00
parent 1b240143c4
commit 1d2d5753b9
2 changed files with 57 additions and 31 deletions

View File

@ -84,7 +84,7 @@ namespace Aurora::IO::FS
auto lock = caller_.lock(); auto lock = caller_.lock();
return lock->Complete(); return lock->Complete();
} }
return false; return false;
} }

View File

@ -645,7 +645,8 @@ namespace Aurora::IO::UNIX
(void)LinuxOverlappedTrySubmitWork(); (void)LinuxOverlappedTrySubmitWork();
} }
} while (timeout || AuExchange(bAgain, false)); }
while (timeout || AuExchange(bAgain, false));
return dwApcsSent; return dwApcsSent;
} }
@ -661,6 +662,8 @@ namespace Aurora::IO::UNIX
{ {
bool bRet { true }; bool bRet { true };
timespec targetTime; timespec targetTime;
int iRedoCount {};
auto io = GetTls(); auto io = GetTls();
if (!io) if (!io)
{ {
@ -698,9 +701,18 @@ namespace Aurora::IO::UNIX
iocb * ptr = &pollSubmit; iocb * ptr = &pollSubmit;
iocb ** ptrArray = &ptr; iocb ** ptrArray = &ptr;
errno = 0; bool bEpollTriggered {};
io_event ioEvents[1024];
AuTuple<ASubmittable *, AuUInt, bool, int> toProcess[1024] {};
int toProcessDone {};
int temp {};
bool bAgain {};
int error; int error;
redo:
toProcessDone = 0;
bEpollTriggered = false;
do do
{ {
error = io_submit(io->context, 1, ptrArray); error = io_submit(io->context, 1, ptrArray);
@ -715,18 +727,11 @@ namespace Aurora::IO::UNIX
{ {
SysPushErrorIO(); SysPushErrorIO();
return -1; return -1;
} };
bool bEpollTriggered {};
io_event ioEvents[1024];
AuTuple<ASubmittable *, AuUInt, bool, int> toProcess[1024] {};
int toProcessDone {};
int temp {};
bool bAgain {};
do do
{ {
if (timeout) if (timeout && !bAgain)
{ {
AuUInt64 uTimeNow = AuTime::SteadyClockNS(); AuUInt64 uTimeNow = AuTime::SteadyClockNS();
if (uTargetTime <= uTimeNow) if (uTargetTime <= uTimeNow)
@ -800,16 +805,12 @@ namespace Aurora::IO::UNIX
SysPanic("io_getevents() is not implemented on this architecture."); SysPanic("io_getevents() is not implemented on this architecture.");
} }
} }
}
bAgain = AuExchange(io->bPollHit, false); while ((timeout ? !bEpollTriggered : false));
if (bAgain)
{
(void)LinuxOverlappedTrySubmitWork();
}
} while ((timeout ? !bEpollTriggered : false) || AuExchange(bAgain, false));
exit: exit:
bAgain = false;
io_event finalEpollEvent {}; io_event finalEpollEvent {};
if (!bEpollTriggered) if (!bEpollTriggered)
{ {
@ -838,6 +839,15 @@ namespace Aurora::IO::UNIX
handle->LIOS_SendProcess(bytesTransacted, bError, errNo); handle->LIOS_SendProcess(bytesTransacted, bError, errNo);
} }
if ((io->submitPendingArray.size() || (bAgain = AuExchange(io->bPollHit, false))))
{
LinuxOverlappedTrySubmitWorkInternal(io);
if (bAgain && (iRedoCount++) < 4)
{
goto redo;
}
}
if (bEpollTriggered) if (bEpollTriggered)
{ {
return epoll_wait(epfd, events, maxevents, 0); return epoll_wait(epfd, events, maxevents, 0);
@ -855,7 +865,17 @@ namespace Aurora::IO::UNIX
bool LinuxOverlappedWaitForOne(AuUInt32 timeout, AuUInt read, AuUInt write, bool &bReadTriggered, bool &bWriteTriggered) bool LinuxOverlappedWaitForOne(AuUInt32 timeout, AuUInt read, AuUInt write, bool &bReadTriggered, bool &bWriteTriggered)
{ {
timespec targetTime; timespec targetTime;
iocb submit {};
iocb readSubmit {};
iocb writeSubmit {};
bool bRet { true }; bool bRet { true };
int iRedoCount {};
io_event ioEvents[1024];
AuTuple<ASubmittable *, AuUInt, bool, int> toProcess[1024] {};
int toProcessDone {};
int temp;
bool bTryAgain {};
auto io = GetTls(); auto io = GetTls();
bWriteTriggered = false; bWriteTriggered = false;
@ -886,9 +906,6 @@ namespace Aurora::IO::UNIX
return false; return false;
} }
iocb submit {};
iocb readSubmit {};
iocb writeSubmit {};
AuMemset(&readSubmit, 0, sizeof(readSubmit)); AuMemset(&readSubmit, 0, sizeof(readSubmit));
AuMemset(&writeSubmit, 0, sizeof(readSubmit)); AuMemset(&writeSubmit, 0, sizeof(readSubmit));
AuMemset(&submit, 0, sizeof(submit)); AuMemset(&submit, 0, sizeof(submit));
@ -915,6 +932,8 @@ namespace Aurora::IO::UNIX
ptrArray[iocbIdx++] = &writeSubmit; ptrArray[iocbIdx++] = &writeSubmit;
} }
redo:
toProcessDone = 0;
int error; int error;
do do
{ {
@ -933,14 +952,9 @@ namespace Aurora::IO::UNIX
return -1; return -1;
} }
io_event ioEvents[1024];
AuTuple<ASubmittable *, AuUInt, bool, int> toProcess[1024] {};
int toProcessDone {};
int temp;
do do
{ {
if (timeout) if (timeout && !bTryAgain)
{ {
AuUInt64 uTimeNow = AuTime::SteadyClockNS(); AuUInt64 uTimeNow = AuTime::SteadyClockNS();
if (uTargetTime <= uTimeNow) if (uTargetTime <= uTimeNow)
@ -1025,9 +1039,12 @@ namespace Aurora::IO::UNIX
} }
} }
} while (timeout ? (!bReadTriggered && !bWriteTriggered) : false); }
while (timeout ? (!bReadTriggered && !bWriteTriggered) : false);
exit: exit:
bTryAgain = false;
for (int i = 0; i < iocbIdx; i++) for (int i = 0; i < iocbIdx; i++)
{ {
io_event finalEpollEvent {}; io_event finalEpollEvent {};
@ -1071,6 +1088,15 @@ namespace Aurora::IO::UNIX
handle->LIOS_SendProcess(bytesTransacted, bError, errNo); handle->LIOS_SendProcess(bytesTransacted, bError, errNo);
} }
if ((io->submitPendingArray.size() || (bTryAgain = AuExchange(io->bPollHit, false))))
{
LinuxOverlappedTrySubmitWorkInternal(io);
if (bTryAgain && (iRedoCount++) < 4)
{
goto redo;
}
}
return bRet; return bRet;
} }