SVC: Fixed WaitSynchronization with multiple handles when none is immediately ready.

This commit is contained in:
Subv 2018-01-09 15:02:43 -05:00
parent bc91ebacc1
commit c2ee513d35

View File

@ -131,7 +131,7 @@ static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thr
ASSERT(reason == ThreadWakeupReason::Signal); ASSERT(reason == ThreadWakeupReason::Signal);
thread->SetWaitSynchronizationResult(RESULT_SUCCESS); thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
thread->SetWaitSynchronizationOutput(static_cast<u32>(index));
return true; return true;
}; };
@ -174,9 +174,10 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
if (!Memory::IsValidVirtualAddress(handles_address)) if (!Memory::IsValidVirtualAddress(handles_address))
return ERR_INVALID_POINTER; return ERR_INVALID_POINTER;
// Check if 'handle_count' is invalid static constexpr u64 MaxHandles = 0x40;
if (handle_count < 0)
return ERR_OUT_OF_RANGE; if (handle_count > MaxHandles)
return ResultCode(ErrorModule::Kernel, ErrCodes::TooLarge);
auto thread = GetCurrentThread(); auto thread = GetCurrentThread();
@ -211,9 +212,19 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
if (nano_seconds == 0) if (nano_seconds == 0)
return RESULT_TIMEOUT; return RESULT_TIMEOUT;
// Just implement for a single handle for now for (auto& object : objects)
ASSERT(handle_count == 1); object->AddWaitingThread(thread);
return WaitSynchronization1(objects[0], GetCurrentThread(), nano_seconds);
thread->wait_objects = std::move(objects);
thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
// Create an event to wake the thread up after the specified nanosecond delay has passed
thread->WakeAfterDelay(nano_seconds);
thread->wakeup_callback = DefaultThreadWakeupCallback;
Core::System::GetInstance().PrepareReschedule();
return RESULT_TIMEOUT;
} }
/// Resumes a thread waiting on WaitSynchronization /// Resumes a thread waiting on WaitSynchronization