diff options
| author | 2021-11-26 15:35:11 -0800 | |
|---|---|---|
| committer | 2021-12-06 16:39:18 -0800 | |
| commit | e3d156ab0e020ade2a96ae82eba226d5f187aa2e (patch) | |
| tree | ea724777749ddb11b649310d83dfda6795add7aa /src/core/hle/kernel/svc.cpp | |
| parent | hle: kernel: k_thread: Treat dummy threads as a special type. (diff) | |
| download | yuzu-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.cpp | 18 |
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. |
| 310 | static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | 310 | static 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(); |