From f5eb684abc0e85bc8c08a27fa7608fa052a86a9a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 May 2013 17:27:38 -0700 Subject: [PATCH] Return an error when there's no async op. And generally improve error codes for async io poll/wait funcs. Fixes #1790. --- Core/HLE/sceIo.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 3b80ac6baf..cfb1afde2a 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -140,7 +140,7 @@ struct dirent { class FileNode : public KernelObject { public: - FileNode() : callbackID(0), callbackArg(0), asyncResult(0), pendingAsyncResult(false), sectorBlockMode(false), closePending(false), npdrm(0), pgdInfo(NULL) {} + FileNode() : callbackID(0), callbackArg(0), asyncResult(0), hasAsyncResult(false), pendingAsyncResult(false), sectorBlockMode(false), closePending(false), npdrm(0), pgdInfo(NULL) {} ~FileNode() { pspFileSystem.CloseFile(handle); } @@ -158,6 +158,7 @@ public: p.Do(callbackID); p.Do(callbackArg); p.Do(asyncResult); + p.Do(hasAsyncResult); p.Do(pendingAsyncResult); p.Do(sectorBlockMode); p.Do(closePending); @@ -176,6 +177,7 @@ public: u32 callbackArg; s64 asyncResult; + bool hasAsyncResult; bool pendingAsyncResult; bool sectorBlockMode; @@ -333,6 +335,7 @@ void __IoCompleteAsyncIO(SceUID id) { __KernelNotifyCallback(THREAD_CALLBACK_IO, f->callbackID, f->callbackArg); } f->pendingAsyncResult = false; + f->hasAsyncResult = true; } } @@ -371,6 +374,7 @@ void __IoSchedAsync(FileNode *f, SceUID fd, int usec) { CoreTiming::ScheduleEvent(usToCycles(usec), asyncNotifyEvent, param); f->pendingAsyncResult = true; + f->hasAsyncResult = false; } u32 sceIoGetstat(const char *filename, u32 addr) { @@ -1245,20 +1249,24 @@ u32 sceIoGetAsyncStat(int id, u32 poll, u32 address) DEBUG_LOG(HLE, "%lli = sceIoGetAsyncStat(%i, %i, %08x): waiting", f->asyncResult, id, poll, address); __KernelWaitCurThread(WAITTYPE_IO, id, address, 0, false, "io waited"); } - } else { + } else if (f->hasAsyncResult) { DEBUG_LOG(HLE, "%lli = sceIoGetAsyncStat(%i, %i, %08x)", f->asyncResult, id, poll, address); Memory::Write_U64((u64) f->asyncResult, address); + f->hasAsyncResult = false; if (f->closePending) { kernelObjects.Destroy(id); } + } else { + WARN_LOG(HLE, "SCE_KERNEL_ERROR_NOASYNC = sceIoGetAsyncStat(%i, %i, %08x)", id, poll, address); + return SCE_KERNEL_ERROR_NOASYNC; } return 0; //completed } else { ERROR_LOG(HLE, "ERROR - sceIoGetAsyncStat with invalid id %i", id); - return -1; + return SCE_KERNEL_ERROR_BADF; } } @@ -1269,18 +1277,22 @@ int sceIoWaitAsync(int id, u32 address) { if (f->pendingAsyncResult) { DEBUG_LOG(HLE, "%lli = sceIoWaitAsync(%i, %08x): waiting", f->asyncResult, id, address); __KernelWaitCurThread(WAITTYPE_IO, id, address, 0, false, "io waited"); - } else { + } else if (f->hasAsyncResult) { DEBUG_LOG(HLE, "%lli = sceIoWaitAsync(%i, %08x)", f->asyncResult, id, address); Memory::Write_U64((u64) f->asyncResult, address); + f->hasAsyncResult = false; if (f->closePending) { kernelObjects.Destroy(id); } + } else { + WARN_LOG(HLE, "SCE_KERNEL_ERROR_NOASYNC = sceIoWaitAsync(%i, %08x)", id, address); + return SCE_KERNEL_ERROR_NOASYNC; } return 0; //completed } else { ERROR_LOG(HLE, "ERROR - sceIoWaitAsync waiting for invalid id %i", id); - return -1; + return SCE_KERNEL_ERROR_BADF; } } @@ -1293,18 +1305,22 @@ int sceIoWaitAsyncCB(int id, u32 address) { if (f->pendingAsyncResult) { DEBUG_LOG(HLE, "%lli = sceIoWaitAsyncCB(%i, %08x): waiting", f->asyncResult, id, address); __KernelWaitCurThread(WAITTYPE_IO, id, address, 0, false, "io waited"); - } else { + } else if (f->hasAsyncResult) { DEBUG_LOG(HLE, "%lli = sceIoWaitAsyncCB(%i, %08x)", f->asyncResult, id, address); Memory::Write_U64((u64) f->asyncResult, address); + f->hasAsyncResult = false; if (f->closePending) { kernelObjects.Destroy(id); } + } else { + WARN_LOG(HLE, "SCE_KERNEL_ERROR_NOASYNC = sceIoWaitAsyncCB(%i, %08x)", id, address); + return SCE_KERNEL_ERROR_NOASYNC; } return 0; //completed } else { ERROR_LOG(HLE, "ERROR - sceIoWaitAsyncCB waiting for invalid id %i", id); - return -1; + return SCE_KERNEL_ERROR_BADF; } } @@ -1315,18 +1331,22 @@ u32 sceIoPollAsync(int id, u32 address) { if (f->pendingAsyncResult) { DEBUG_LOG(HLE, "%lli = sceIoPollAsync(%i, %08x): not ready", f->asyncResult, id, address); return 1; - } else { + } else if (f->hasAsyncResult) { DEBUG_LOG(HLE, "%lli = sceIoPollAsync(%i, %08x)", f->asyncResult, id, address); Memory::Write_U64((u64) f->asyncResult, address); + f->hasAsyncResult = false; if (f->closePending) { kernelObjects.Destroy(id); } return 0; //completed + } else { + WARN_LOG(HLE, "SCE_KERNEL_ERROR_NOASYNC = sceIoWaitAsyncCB(%i, %08x)", id, address); + return SCE_KERNEL_ERROR_NOASYNC; } } else { ERROR_LOG(HLE, "ERROR - sceIoPollAsync waiting for invalid id %i", id); - return -1; // TODO: correct error code + return SCE_KERNEL_ERROR_BADF; } }