mirror of https://github.com/PCSX2/pcsx2.git
macOS: Fix async file reader error handling
Should fall back to blocking io if aio fails
This commit is contained in:
parent
1a29a6da1d
commit
87c56ccfc4
|
@ -79,7 +79,7 @@ class FlatFileReader : public AsyncFileReader
|
||||||
#elif defined(__POSIX__)
|
#elif defined(__POSIX__)
|
||||||
int m_fd; // TODO OSX don't know if overlap as an equivalent on OSX
|
int m_fd; // TODO OSX don't know if overlap as an equivalent on OSX
|
||||||
struct aiocb m_aiocb;
|
struct aiocb m_aiocb;
|
||||||
bool m_read_in_progress;
|
bool m_async_read_in_progress;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool shareWrite;
|
bool shareWrite;
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "AsyncFileReader.h"
|
#include "AsyncFileReader.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#warning Tested on FreeBSD, not OS X. Be very afraid.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The aio module has been reported to cause issues with FreeBSD 10.3, so let's
|
// The aio module has been reported to cause issues with FreeBSD 10.3, so let's
|
||||||
// disable it for 10.3 and earlier and hope FreeBSD 11 and onwards is fine.
|
// disable it for 10.3 and earlier and hope FreeBSD 11 and onwards is fine.
|
||||||
// Note: It may be worth checking whether aio provides any performance benefit.
|
// Note: It may be worth checking whether aio provides any performance benefit.
|
||||||
|
@ -32,7 +28,7 @@ FlatFileReader::FlatFileReader(bool shareWrite) : shareWrite(shareWrite)
|
||||||
{
|
{
|
||||||
m_blocksize = 2048;
|
m_blocksize = 2048;
|
||||||
m_fd = -1;
|
m_fd = -1;
|
||||||
m_read_in_progress = false;
|
m_async_read_in_progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatFileReader::~FlatFileReader(void)
|
FlatFileReader::~FlatFileReader(void)
|
||||||
|
@ -61,61 +57,69 @@ void FlatFileReader::BeginRead(void* pBuffer, uint sector, uint count)
|
||||||
|
|
||||||
u32 bytesToRead = count * m_blocksize;
|
u32 bytesToRead = count * m_blocksize;
|
||||||
|
|
||||||
#if defined(DISABLE_AIO)
|
m_async_read_in_progress = false;
|
||||||
m_aiocb.aio_nbytes = pread(m_fd, pBuffer, bytesToRead, offset);
|
#ifndef DISABLE_AIO
|
||||||
if (m_aiocb.aio_nbytes != bytesToRead)
|
|
||||||
m_aiocb.aio_nbytes = -1;
|
|
||||||
#else
|
|
||||||
m_aiocb = {0};
|
m_aiocb = {0};
|
||||||
m_aiocb.aio_fildes = m_fd;
|
m_aiocb.aio_fildes = m_fd;
|
||||||
m_aiocb.aio_offset = offset;
|
m_aiocb.aio_offset = offset;
|
||||||
m_aiocb.aio_nbytes = bytesToRead;
|
m_aiocb.aio_nbytes = bytesToRead;
|
||||||
m_aiocb.aio_buf = pBuffer;
|
m_aiocb.aio_buf = pBuffer;
|
||||||
|
|
||||||
if (aio_read(&m_aiocb) != 0) {
|
if (aio_read(&m_aiocb) == 0)
|
||||||
|
{
|
||||||
|
m_async_read_in_progress = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
if (errno == ENOSYS)
|
case ENOSYS:
|
||||||
Console.Error("AIO read failed: Check the aio kernel module is loaded");
|
Console.Error("AIO read failed: Check the aio kernel module is loaded");
|
||||||
else
|
break;
|
||||||
Console.Error("AIO read failed: error code %d", errno);
|
|
||||||
#else
|
|
||||||
Console.Error("AIO read failed: error code %d\n", errno);
|
|
||||||
#endif
|
#endif
|
||||||
return;
|
case EAGAIN:
|
||||||
|
Console.Warning("AIO read failed: Out of resources. Will read synchronously");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Console.Error("AIO read failed: error code %d\n", errno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
m_read_in_progress = true;
|
if (!m_async_read_in_progress)
|
||||||
|
{
|
||||||
|
m_aiocb.aio_nbytes = pread(m_fd, pBuffer, bytesToRead, offset);
|
||||||
|
if (m_aiocb.aio_nbytes != bytesToRead)
|
||||||
|
m_aiocb.aio_nbytes = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FlatFileReader::FinishRead(void)
|
int FlatFileReader::FinishRead(void)
|
||||||
{
|
{
|
||||||
#if defined(DISABLE_AIO)
|
if (!m_async_read_in_progress)
|
||||||
m_read_in_progress = false;
|
return m_aiocb.aio_nbytes == (size_t)-1 ? -1 : 1;
|
||||||
return m_aiocb.aio_nbytes == (size_t)-1 ? -1: 1;
|
m_async_read_in_progress = true;
|
||||||
#else
|
|
||||||
struct aiocb *aiocb_list[] = {&m_aiocb};
|
struct aiocb *aiocb_list[] = {&m_aiocb};
|
||||||
|
|
||||||
while (aio_suspend(aiocb_list, 1, nullptr) == -1)
|
while (aio_suspend(aiocb_list, 1, nullptr) == -1 && errno == EINTR)
|
||||||
if (errno != EINTR)
|
;
|
||||||
break;
|
return aio_return(&m_aiocb) == -1 ? -1 : 1;
|
||||||
|
|
||||||
m_read_in_progress = false;
|
|
||||||
return aio_return(&m_aiocb) == -1? -1: 1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatFileReader::CancelRead(void)
|
void FlatFileReader::CancelRead(void)
|
||||||
{
|
{
|
||||||
#if !defined(DISABLE_AIO)
|
if (m_async_read_in_progress)
|
||||||
aio_cancel(m_fd, &m_aiocb);
|
{
|
||||||
#endif
|
aio_cancel(m_fd, &m_aiocb);
|
||||||
m_read_in_progress = false;
|
m_async_read_in_progress = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatFileReader::Close(void)
|
void FlatFileReader::Close(void)
|
||||||
{
|
{
|
||||||
if (m_read_in_progress)
|
CancelRead();
|
||||||
CancelRead();
|
|
||||||
if (m_fd != -1)
|
if (m_fd != -1)
|
||||||
close(m_fd);
|
close(m_fd);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue