summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2021-11-26 15:35:11 -0800
committerGravatar bunnei2021-12-06 16:39:18 -0800
commite3d156ab0e020ade2a96ae82eba226d5f187aa2e (patch)
treeea724777749ddb11b649310d83dfda6795add7aa /src/core/hle/kernel/svc.cpp
parenthle: kernel: k_thread: Treat dummy threads as a special type. (diff)
downloadyuzu-e3d156ab0e020ade2a96ae82eba226d5f187aa2e.tar.gz
yuzu-e3d156ab0e020ade2a96ae82eba226d5f187aa2e.tar.xz
yuzu-e3d156ab0e020ade2a96ae82eba226d5f187aa2e.zip
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 0e79e1be3..359cf515d 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,
308 308
309/// Makes a blocking IPC call to an OS service. 309/// Makes a blocking IPC call to an OS service.
310static ResultCode SendSyncRequest(Core::System& system, Handle handle) { 310static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
311
312 auto& kernel = system.Kernel(); 311 auto& kernel = system.Kernel();
313 312
314 // Create the wait queue. 313 // Create the wait queue.
315 KThreadQueue wait_queue(kernel); 314 KThreadQueue wait_queue(kernel);
316 315
316 // Get the client session from its handle.
317 KScopedAutoObject session =
318 kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
319 R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
320
321 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
322
317 auto thread = kernel.CurrentScheduler()->GetCurrentThread(); 323 auto thread = kernel.CurrentScheduler()->GetCurrentThread();
318 { 324 {
319 KScopedSchedulerLock lock(kernel); 325 KScopedSchedulerLock lock(kernel);
@@ -321,15 +327,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
321 // This is a synchronous request, so we should wait for our request to complete. 327 // This is a synchronous request, so we should wait for our request to complete.
322 GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue)); 328 GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
323 GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); 329 GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
324 330 session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
325 {
326 KScopedAutoObject session =
327 kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
328 R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
329 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
330 session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(),
331 system.CoreTiming());
332 }
333 } 331 }
334 332
335 return thread->GetWaitResult(); 333 return thread->GetWaitResult();