summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar bunnei2021-06-08 13:39:20 -0700
committerGravatar bunnei2021-06-08 13:39:20 -0700
commitb8fb9b3f112cb43831aeac8ab1242ae653989067 (patch)
treec41f1964e65d2f398af4be26d92ca80370880f51 /src/core/hle/kernel
parenthle: kernel: hle_ipc: Ensure SessionRequestHandler is valid. (diff)
downloadyuzu-b8fb9b3f112cb43831aeac8ab1242ae653989067.tar.gz
yuzu-b8fb9b3f112cb43831aeac8ab1242ae653989067.tar.xz
yuzu-b8fb9b3f112cb43831aeac8ab1242ae653989067.zip
hle: kernel: KServerSession: Work-around scenario where session is closed too early.
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/k_server_session.cpp31
1 files changed, 24 insertions, 7 deletions
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index dd62706a8..5c3c13ce6 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -8,6 +8,7 @@
8#include "common/assert.h" 8#include "common/assert.h"
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "common/scope_exit.h"
11#include "core/core_timing.h" 12#include "core/core_timing.h"
12#include "core/hle/ipc_helpers.h" 13#include "core/hle/ipc_helpers.h"
13#include "core/hle/kernel/hle_ipc.h" 14#include "core/hle/kernel/hle_ipc.h"
@@ -119,11 +120,20 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor
119 120
120 context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); 121 context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
121 122
123 // In the event that something fails here, stub a result to prevent the game from crashing.
124 // This is a work-around in the event that somehow we process a service request after the
125 // session has been closed by the game. This has been observed to happen rarely in Pokemon
126 // Sword/Shield and is likely a result of us using host threads/scheduling for services.
127 // TODO(bunnei): Find a better solution here.
128 auto error_guard = SCOPE_GUARD({ CompleteSyncRequest(*context); });
129
122 // Ensure we have a session request handler 130 // Ensure we have a session request handler
123 if (manager->HasSessionRequestHandler(*context)) { 131 if (manager->HasSessionRequestHandler(*context)) {
124 if (auto strong_ptr = manager->GetServiceThread().lock()) { 132 if (auto strong_ptr = manager->GetServiceThread().lock()) {
125 strong_ptr->QueueSyncRequest(*parent, std::move(context)); 133 strong_ptr->QueueSyncRequest(*parent, std::move(context));
126 return ResultSuccess; 134
135 // We succeeded.
136 error_guard.Cancel();
127 } else { 137 } else {
128 ASSERT_MSG(false, "strong_ptr is nullptr!"); 138 ASSERT_MSG(false, "strong_ptr is nullptr!");
129 } 139 }
@@ -136,13 +146,20 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor
136 146
137ResultCode KServerSession::CompleteSyncRequest(HLERequestContext& context) { 147ResultCode KServerSession::CompleteSyncRequest(HLERequestContext& context) {
138 ResultCode result = ResultSuccess; 148 ResultCode result = ResultSuccess;
149
139 // If the session has been converted to a domain, handle the domain request 150 // If the session has been converted to a domain, handle the domain request
140 if (IsDomain() && context.HasDomainMessageHeader()) { 151 if (manager->HasSessionRequestHandler(context)) {
141 result = HandleDomainSyncRequest(context); 152 if (IsDomain() && context.HasDomainMessageHeader()) {
142 // If there is no domain header, the regular session handler is used 153 result = HandleDomainSyncRequest(context);
143 } else if (manager->HasSessionHandler()) { 154 // If there is no domain header, the regular session handler is used
144 // If this ServerSession has an associated HLE handler, forward the request to it. 155 } else if (manager->HasSessionHandler()) {
145 result = manager->SessionHandler().HandleSyncRequest(*this, context); 156 // If this ServerSession has an associated HLE handler, forward the request to it.
157 result = manager->SessionHandler().HandleSyncRequest(*this, context);
158 }
159 } else {
160 ASSERT_MSG(false, "Session handler is invalid, stubbing response!");
161 IPC::ResponseBuilder rb(context, 2);
162 rb.Push(ResultSuccess);
146 } 163 }
147 164
148 if (convert_to_domain) { 165 if (convert_to_domain) {