From 2c40cd509af76a6201796dc1286c0dc02e1ba2bc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 2 Mar 2014 13:45:12 -0800 Subject: [PATCH] Avoid overwriting io thread results. Just block until it's done so that things are synchronous. --- Core/HLE/sceIo.cpp | 23 +++++++++++++++++++++-- Core/HW/AsyncIOManager.cpp | 10 ++++++++++ Core/HW/AsyncIOManager.h | 1 + 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 1aadd248e8..9492b72135 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -742,7 +742,17 @@ bool __IoRead(int &result, int id, u32 data_addr, int size) { if (f->npdrm) { result = npdrmRead(f, data, size); return true; - } else if (__KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE) { + } + + bool useThread = __KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE; + if (useThread) { + // If there's a pending operation on this file, wait for it to finish and don't overwrite it. + useThread = !ioManager.HasOperation(f->handle); + if (!useThread) { + ioManager.SyncThread(); + } + } + if (useThread) { AsyncIOEvent ev = IO_EVENT_READ; ev.handle = f->handle; ev.buf = data; @@ -854,7 +864,16 @@ bool __IoWrite(int &result, int id, u32 data_addr, int size) { result = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; return true; } - if (__KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE) { + + bool useThread = __KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE; + if (useThread) { + // If there's a pending operation on this file, wait for it to finish and don't overwrite it. + useThread = !ioManager.HasOperation(f->handle); + if (!useThread) { + ioManager.SyncThread(); + } + } + if (useThread) { AsyncIOEvent ev = IO_EVENT_WRITE; ev.handle = f->handle; ev.buf = (u8 *) data_ptr; diff --git a/Core/HW/AsyncIOManager.cpp b/Core/HW/AsyncIOManager.cpp index 0bf29f1134..3ff26be160 100644 --- a/Core/HW/AsyncIOManager.cpp +++ b/Core/HW/AsyncIOManager.cpp @@ -21,6 +21,16 @@ #include "Core/HW/AsyncIOManager.h" #include "Core/FileSystems/MetaFileSystem.h" +bool AsyncIOManager::HasOperation(u32 handle) { + if (resultsPending_.find(handle) != resultsPending_.end()) { + return true; + } + if (results_.find(handle) != results_.end()) { + return true; + } + return false; +} + void AsyncIOManager::ScheduleOperation(AsyncIOEvent ev) { lock_guard guard(resultsLock_); if (!resultsPending_.insert(ev.handle).second) { diff --git a/Core/HW/AsyncIOManager.h b/Core/HW/AsyncIOManager.h index d2aacfa316..8fb96a16ee 100644 --- a/Core/HW/AsyncIOManager.h +++ b/Core/HW/AsyncIOManager.h @@ -51,6 +51,7 @@ class AsyncIOManager : public IOThreadEventQueue { public: void DoState(PointerWrap &p); + bool HasOperation(u32 handle); void ScheduleOperation(AsyncIOEvent ev); void Shutdown();