mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-25 09:09:49 +00:00
Add io async wait callback handlers.
This commit is contained in:
parent
d8d8d3b0ec
commit
1eb858602c
@ -274,7 +274,7 @@ void __IoFreeFd(int fd, u32 &error) {
|
||||
if (f) {
|
||||
// Wake anyone waiting on the file before closing it.
|
||||
for (size_t i = 0; i < f->waitingThreads.size(); ++i) {
|
||||
HLEKernel::ResumeFromWait(f->waitingThreads[i], WAITTYPE_ASYNCIO, fd, SCE_KERNEL_ERROR_WAIT_DELETE);
|
||||
HLEKernel::ResumeFromWait(f->waitingThreads[i], WAITTYPE_ASYNCIO, f->GetUID(), SCE_KERNEL_ERROR_WAIT_DELETE);
|
||||
}
|
||||
}
|
||||
error = kernelObjects.Destroy<FileNode>(fds[fd]);
|
||||
@ -316,8 +316,8 @@ void __IoAsyncNotify(u64 userdata, int cyclesLate) {
|
||||
f->waitingThreads.erase(f->waitingThreads.begin());
|
||||
|
||||
u32 address = __KernelGetWaitValue(threadID, error);
|
||||
if (HLEKernel::VerifyWait(threadID, WAITTYPE_ASYNCIO, fd)) {
|
||||
HLEKernel::ResumeFromWait(threadID, WAITTYPE_ASYNCIO, fd, 0);
|
||||
if (HLEKernel::VerifyWait(threadID, WAITTYPE_ASYNCIO, f->GetUID())) {
|
||||
HLEKernel::ResumeFromWait(threadID, WAITTYPE_ASYNCIO, f->GetUID(), 0);
|
||||
|
||||
if (Memory::IsValidAddress(address)) {
|
||||
Memory::Write_U64((u64) f->asyncResult, address);
|
||||
@ -355,6 +355,60 @@ void __IoSyncNotify(u64 userdata, int cyclesLate) {
|
||||
HLEKernel::ResumeFromWait(threadID, WAITTYPE_IO, fd, result);
|
||||
}
|
||||
|
||||
void __IoAsyncBeginCallback(SceUID threadID, SceUID prevCallbackId) {
|
||||
auto result = HLEKernel::WaitBeginCallback<FileNode, WAITTYPE_ASYNCIO, SceUID>(threadID, prevCallbackId, -1);
|
||||
if (result == HLEKernel::WAIT_CB_SUCCESS) {
|
||||
DEBUG_LOG(HLE, "sceIoWaitAsync: Suspending wait for callback")
|
||||
} else if (result == HLEKernel::WAIT_CB_BAD_WAIT_ID) {
|
||||
WARN_LOG_REPORT(HLE, "sceIoWaitAsync: beginning callback with bad wait id?");
|
||||
}
|
||||
}
|
||||
|
||||
bool __IoCheckAsyncWait(FileNode *f, SceUID threadID, u32 &error, int result, bool &wokeThreads)
|
||||
{
|
||||
int fd = -1;
|
||||
for (int i = 0; i < (int)ARRAY_SIZE(fds); ++i) {
|
||||
if (fds[i] == f->GetUID()) {
|
||||
fd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd == -1) {
|
||||
ERROR_LOG_REPORT(HLE, "__IoCheckAsyncWait: could not find io handle");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!HLEKernel::VerifyWait(threadID, WAITTYPE_ASYNCIO, f->GetUID())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If result is an error code, we're just letting it go.
|
||||
if (result == 0) {
|
||||
if (f->pendingAsyncResult || !f->hasAsyncResult) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 address = __KernelGetWaitValue(threadID, error);
|
||||
Memory::Write_U64((u64) f->asyncResult, address);
|
||||
f->hasAsyncResult = false;
|
||||
|
||||
if (f->closePending) {
|
||||
__IoFreeFd(fd, error);
|
||||
}
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, result);
|
||||
wokeThreads = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void __IoAsyncEndCallback(SceUID threadID, SceUID prevCallbackId) {
|
||||
auto result = HLEKernel::WaitEndCallback<FileNode, WAITTYPE_ASYNCIO, SceUID>(threadID, prevCallbackId, -1, __IoCheckAsyncWait);
|
||||
if (result == HLEKernel::WAIT_CB_RESUMED_WAIT) {
|
||||
DEBUG_LOG(HLE, "sceKernelWaitEventFlagCB: Resuming lock wait for callback");
|
||||
}
|
||||
}
|
||||
|
||||
static DirectoryFileSystem *memstickSystem = NULL;
|
||||
#ifdef ANDROID
|
||||
static VFSFileSystem *flash0System = NULL;
|
||||
@ -401,6 +455,8 @@ void __IoInit() {
|
||||
if (ioManagerThreadEnabled) {
|
||||
ioManagerThread = new std::thread(&__IoManagerThread);
|
||||
}
|
||||
|
||||
__KernelRegisterWaitTypeFuncs(WAITTYPE_ASYNCIO, __IoAsyncBeginCallback, __IoAsyncEndCallback);
|
||||
}
|
||||
|
||||
void __IoDoState(PointerWrap &p) {
|
||||
@ -1544,7 +1600,7 @@ u32 sceIoGetAsyncStat(int id, u32 poll, u32 address) {
|
||||
|
||||
DEBUG_LOG(HLE, "%lli = sceIoGetAsyncStat(%i, %i, %08x): waiting", f->asyncResult, id, poll, address);
|
||||
f->waitingThreads.push_back(__KernelGetCurThread());
|
||||
__KernelWaitCurThread(WAITTYPE_ASYNCIO, id, address, 0, false, "io waited");
|
||||
__KernelWaitCurThread(WAITTYPE_ASYNCIO, f->GetUID(), address, 0, false, "io waited");
|
||||
}
|
||||
} else if (f->hasAsyncResult) {
|
||||
if (!__KernelIsDispatchEnabled()) {
|
||||
@ -1587,7 +1643,7 @@ int sceIoWaitAsync(int id, u32 address) {
|
||||
}
|
||||
DEBUG_LOG(HLE, "%lli = sceIoWaitAsync(%i, %08x): waiting", f->asyncResult, id, address);
|
||||
f->waitingThreads.push_back(__KernelGetCurThread());
|
||||
__KernelWaitCurThread(WAITTYPE_ASYNCIO, id, address, 0, false, "io waited");
|
||||
__KernelWaitCurThread(WAITTYPE_ASYNCIO, f->GetUID(), address, 0, false, "io waited");
|
||||
} else if (f->hasAsyncResult) {
|
||||
if (!__KernelIsDispatchEnabled()) {
|
||||
DEBUG_LOG(HLE, "%lli = sceIoWaitAsync(%i, %08x): dispatch disabled", f->asyncResult, id, address);
|
||||
@ -1626,7 +1682,7 @@ int sceIoWaitAsyncCB(int id, u32 address) {
|
||||
DEBUG_LOG(HLE, "%lli = sceIoWaitAsyncCB(%i, %08x): waiting", f->asyncResult, id, address);
|
||||
// TODO: This seems to re-enable dispatch or something?
|
||||
f->waitingThreads.push_back(__KernelGetCurThread());
|
||||
__KernelWaitCurThread(WAITTYPE_ASYNCIO, id, address, 0, false, "io waited");
|
||||
__KernelWaitCurThread(WAITTYPE_ASYNCIO, f->GetUID(), address, 0, false, "io waited");
|
||||
} else if (f->hasAsyncResult) {
|
||||
DEBUG_LOG(HLE, "%lli = sceIoWaitAsyncCB(%i, %08x)", f->asyncResult, id, address);
|
||||
Memory::Write_U64((u64) f->asyncResult, address);
|
||||
|
Loading…
Reference in New Issue
Block a user