From 064be2b86f166d40e0ba61bc4ec0306631b4be9f Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 17 Jan 2015 12:17:36 -0500 Subject: WaitSynchronizationN: Handle case where handle_count=0. --- src/core/hle/svc.cpp | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 170ac87f..f8a5b254 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -148,27 +148,37 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all_succeeded = false; int handle_index = 0; - while (handle_index < handle_count) { - SharedPtr object = Kernel::g_handle_table.GetGeneric(handles[handle_index]); - if (object == nullptr) - return InvalidHandle(ErrorModule::Kernel).raw; - - ResultVal wait = object->WaitSynchronization(handle_index); - - wait_thread = (wait.Succeeded() && *wait); + // If handles were passed in, iterate through them and wait/acquire the objects as needed + if (handle_count > 0) { + while (handle_index < handle_count) { + SharedPtr object = Kernel::g_handle_table.GetGeneric(handles[handle_index]); + if (object == nullptr) + return InvalidHandle(ErrorModule::Kernel).raw; + + ResultVal wait = object->WaitSynchronization(handle_index); + + wait_thread = (wait.Succeeded() && *wait); + + // If this object waited and we are waiting on all objects to synchronize + if (wait_thread && wait_all) { + // Enforce later on that this thread does not continue + wait_all_succeeded = true; + } + + // If this object synchronized and we are not waiting on all objects to synchronize + if (!wait_thread && !wait_all) + // We're done, the thread will continue + break; - // If this object waited and we are waiting on all objects to synchronize - if (wait_thread && wait_all) { - // Enforce later on that this thread does not continue - wait_all_succeeded = true; + handle_index++; + } + }else { + // If no handles were passed in, put the thread to sleep only when wait_all=false + // NOTE: This is supposed to deadlock if no timeout was specified + if (!wait_all) { + wait_thread = true; + Kernel::WaitCurrentThread(WAITTYPE_SLEEP); } - - // If this object synchronized and we are not waiting on all objects to synchronize - if (!wait_thread && !wait_all) - // We're done, the thread will continue - break; - - handle_index++; } // Change the thread state to waiting if blocking on all handles... -- cgit v1.2.3