aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2021-11-26 15:35:11 -0800
committerbunnei <bunneidev@gmail.com>2021-12-06 16:39:18 -0800
commite3d156ab0e020ade2a96ae82eba226d5f187aa2e (patch)
treeea724777749ddb11b649310d83dfda6795add7aa /src/core/hle/kernel/svc.cpp
parent0d9afdedc4ef9c0861739b04fc9a53926305e1f3 (diff)
hle: kernel: svc: Fix deadlock that can occur with single core.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp18
1 files changed, 8 insertions, 10 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 0e79e1be3d..359cf515df 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -308,12 +308,18 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle,
/// Makes a blocking IPC call to an OS service.
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
-
auto& kernel = system.Kernel();
// Create the wait queue.
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();
{
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.
GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
-
- {
- 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());
- }
+ session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
}
return thread->GetWaitResult();