hle: kernel: svc: Fix deadlock that can occur with single core.

This commit is contained in:
bunnei 2021-11-26 15:35:11 -08:00
parent 0d9afdedc4
commit e3d156ab0e

View File

@ -308,12 +308,18 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle,
/// Makes a blocking IPC call to an OS service. /// Makes a blocking IPC call to an OS service.
static ResultCode SendSyncRequest(Core::System& system, Handle handle) { static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
auto& kernel = system.Kernel(); auto& kernel = system.Kernel();
// Create the wait queue. // Create the wait queue.
KThreadQueue wait_queue(kernel); KThreadQueue wait_queue(kernel);
// Get the client session from its handle.
KScopedAutoObject session =
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
auto thread = kernel.CurrentScheduler()->GetCurrentThread(); auto thread = kernel.CurrentScheduler()->GetCurrentThread();
{ {
KScopedSchedulerLock lock(kernel); KScopedSchedulerLock lock(kernel);
@ -321,15 +327,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
// This is a synchronous request, so we should wait for our request to complete. // This is a synchronous request, so we should wait for our request to complete.
GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue)); GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
{
KScopedAutoObject session =
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(),
system.CoreTiming());
}
} }
return thread->GetWaitResult(); return thread->GetWaitResult();