[*] Linux: fix spinning in an io_submit=EAGAIN loop
This commit is contained in:
parent
5947e6a2c3
commit
75f6325ee2
@ -609,6 +609,10 @@ namespace Aurora::IO::FS
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this->pCompletionGroup_ && !this->loopSource_)
|
||||
{
|
||||
this->loopSource_ = AuMakeShared<LinuxAsyncFileTransactionLoopSource>(AuSharedFromThis());
|
||||
}
|
||||
return AuStaticCast<Loop::ILoopSource>(AuStaticCast<Loop::ILSEvent>(this->loopSource_));
|
||||
}
|
||||
}
|
||||
|
@ -263,6 +263,14 @@ namespace Aurora::IO::UNIX
|
||||
// GLUE
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
static void HandleEAGAIN()
|
||||
{
|
||||
// DO NOT
|
||||
LinuxOverlappedYield();
|
||||
// CHANGE!
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
static bool LinuxOverlappedTrySubmitWorkInternal(TLSIO *io)
|
||||
{
|
||||
int index {};
|
||||
@ -270,7 +278,16 @@ namespace Aurora::IO::UNIX
|
||||
|
||||
while (index != startingLength)
|
||||
{
|
||||
int ret = io_submit(io->context, io->submitPendingArray.size() - index, io->submitPendingArray.data() + index);
|
||||
int ret;
|
||||
do
|
||||
{
|
||||
ret = io_submit(io->context, io->submitPendingArray.size() - index, io->submitPendingArray.data() + index);
|
||||
if (ret == -EAGAIN)
|
||||
{
|
||||
HandleEAGAIN();
|
||||
}
|
||||
}
|
||||
while (ret == -EAGAIN);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
@ -377,6 +394,7 @@ namespace Aurora::IO::UNIX
|
||||
context->abortContext = io->context;
|
||||
|
||||
iocb &submit = context->GetIOCB();
|
||||
AuMemset(&submit, 0, sizeof(submit));
|
||||
submit.aio_data = context->GetData();
|
||||
submit.aio_lio_opcode = op;
|
||||
submit.aio_reqprio = 0;
|
||||
@ -694,6 +712,7 @@ namespace Aurora::IO::UNIX
|
||||
// evil nested epoll garbage
|
||||
// but i'm sure the kevent way would be more inefficient
|
||||
iocb pollSubmit {};
|
||||
AuMemset(&pollSubmit, 0, sizeof(pollSubmit));
|
||||
pollSubmit.aio_fildes = epfd;
|
||||
pollSubmit.aio_lio_opcode = IOCB_CMD_POLL;
|
||||
pollSubmit.aio_buf = POLLIN;
|
||||
@ -701,9 +720,21 @@ namespace Aurora::IO::UNIX
|
||||
iocb * ptr = &pollSubmit;
|
||||
iocb ** ptrArray = &ptr;
|
||||
|
||||
if (io_submit(io->context, 1, ptrArray) <= 0)
|
||||
errno = 0;
|
||||
|
||||
int error;
|
||||
do
|
||||
{
|
||||
error = io_submit(io->context, 1, ptrArray);
|
||||
if (error == -EAGAIN)
|
||||
{
|
||||
HandleEAGAIN();
|
||||
}
|
||||
}
|
||||
while (error == -EAGAIN);
|
||||
|
||||
if (error <= 0)
|
||||
{
|
||||
errno = EFAULT;
|
||||
SysPushErrorIO();
|
||||
return -1;
|
||||
}
|
||||
@ -797,7 +828,7 @@ namespace Aurora::IO::UNIX
|
||||
io_event finalEpollEvent {};
|
||||
if (!bEpollTriggered)
|
||||
{
|
||||
if (io_cancel(io->context, ptr, &finalEpollEvent) != 0)
|
||||
if (io_cancel(io->context, &pollSubmit, &finalEpollEvent) != 0)
|
||||
{
|
||||
if (errno != EINPROGRESS)
|
||||
{
|
||||
@ -864,6 +895,9 @@ namespace Aurora::IO::UNIX
|
||||
iocb submit {};
|
||||
iocb readSubmit {};
|
||||
iocb writeSubmit {};
|
||||
AuMemset(&readSubmit, 0, sizeof(readSubmit));
|
||||
AuMemset(&writeSubmit, 0, sizeof(readSubmit));
|
||||
AuMemset(&submit, 0, sizeof(submit));
|
||||
submit.aio_lio_opcode = IOCB_CMD_POLL;
|
||||
|
||||
iocb * ptrArray[2];
|
||||
@ -887,7 +921,18 @@ namespace Aurora::IO::UNIX
|
||||
ptrArray[iocbIdx++] = &writeSubmit;
|
||||
}
|
||||
|
||||
if (io_submit(io->context, iocbIdx, ptrArray) <= 0)
|
||||
int error;
|
||||
do
|
||||
{
|
||||
error = io_submit(io->context, iocbIdx, ptrArray);
|
||||
if (error == -EAGAIN)
|
||||
{
|
||||
HandleEAGAIN();
|
||||
}
|
||||
}
|
||||
while (error == -EAGAIN);
|
||||
|
||||
if (error <= 0)
|
||||
{
|
||||
errno = EFAULT;
|
||||
SysPushErrorIO();
|
||||
|
Loading…
Reference in New Issue
Block a user