Don't run wait callback hooks for a thread that isn't waiting

A thread whose wait ends without a context switch (for example when a
callback run from the wait satisfies it) keeps its old waitType. If it
later ran a callback, from sceUmdWaitDriveStatCB with the drive already
ready for instance, the stale wait's begin/end hooks ran, couldn't find
the paused wait, and resumed the thread with SCE_KERNEL_ERROR_WAIT_DELETE,
overwriting the HLE call's return value.

Should fix "sceUmdWaitDriveStatCB: error 0x800201b5" dialog in
Maru Goukaku TOEIC Test Portable (#7576).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-09-28 15:58:47 -06:00
1 parent 91a34056d0
commit e7c23bb381
1 file changed
+4 -3
+4 -3
View File
@@ -3090,8 +3090,9 @@ void __KernelCallAddress(PSPThread *thread, u32 entryPoint, PSPAction *afterActi
afterAction = after;
if (thread->nt.waitType != WAITTYPE_NONE) {
// If it's a callback, tell the wait to stop.
if (cbId > 0) {
// If it's a callback, tell the wait to stop. A thread that already returned from its
// wait keeps a stale waitType until it's switched out, so check that it's waiting.
if (cbId > 0 && (thread->nt.status & THREADSTATUS_WAIT) != 0) {
if (waitTypeFuncs[thread->nt.waitType].beginFunc != NULL) {
waitTypeFuncs[thread->nt.waitType].beginFunc(after->threadID, thread->currentCallbackId);
} else {
@@ -3250,7 +3251,7 @@ void __KernelReturnFromMipsCall() {
}
currentCallbackThreadID = 0;
if (cur->nt.waitType != WAITTYPE_NONE && call->cbId > 0) {
if (cur->nt.waitType != WAITTYPE_NONE && (cur->nt.status & THREADSTATUS_WAIT) != 0 && call->cbId > 0) {
if (waitTypeFuncs[cur->nt.waitType].endFunc != NULL)
waitTypeFuncs[cur->nt.waitType].endFunc(cur->GetUID(), cur->currentCallbackId);
else