summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2019-11-25 18:17:08 -0500
committerGravatar bunnei2019-11-25 18:17:49 -0500
commitf6b9b7910eb59cdc1e3aea9a1f1cb3d1cf8ae7f6 (patch)
tree2514317ed0d0ada5de3a219bdd1f5baa635760dc /src
parentMerge pull request #3160 from DarkLordZach/opt-ea-clang-fmt (diff)
downloadyuzu-f6b9b7910eb59cdc1e3aea9a1f1cb3d1cf8ae7f6.tar.gz
yuzu-f6b9b7910eb59cdc1e3aea9a1f1cb3d1cf8ae7f6.tar.xz
yuzu-f6b9b7910eb59cdc1e3aea9a1f1cb3d1cf8ae7f6.zip
kernel: Fix reference management for client/server session.
- Fixes shutdown crash and crash in Pokemon SwSh.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/client_session.cpp16
-rw-r--r--src/core/hle/kernel/server_session.cpp18
-rw-r--r--src/core/hle/kernel/session.h4
3 files changed, 18 insertions, 20 deletions
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp
index bc59d3306..5995a6556 100644
--- a/src/core/hle/kernel/client_session.cpp
+++ b/src/core/hle/kernel/client_session.cpp
@@ -16,20 +16,18 @@ ClientSession::ClientSession(KernelCore& kernel) : Object{kernel} {}
16ClientSession::~ClientSession() { 16ClientSession::~ClientSession() {
17 // This destructor will be called automatically when the last ClientSession handle is closed by 17 // This destructor will be called automatically when the last ClientSession handle is closed by
18 // the emulated application. 18 // the emulated application.
19 if (parent->server) { 19 if (auto server = parent->server.lock()) {
20 parent->server->ClientDisconnected(); 20 server->ClientDisconnected();
21 } 21 }
22
23 parent->client = nullptr;
24} 22}
25 23
26ResultCode ClientSession::SendSyncRequest(Thread* thread) { 24ResultCode ClientSession::SendSyncRequest(Thread* thread) {
27 // Keep ServerSession alive until we're done working with it.
28 if (parent->server == nullptr)
29 return ERR_SESSION_CLOSED_BY_REMOTE;
30
31 // Signal the server session that new data is available 25 // Signal the server session that new data is available
32 return parent->server->HandleSyncRequest(SharedFrom(thread)); 26 if (auto server = parent->server.lock()) {
27 return server->HandleSyncRequest(SharedFrom(thread));
28 }
29
30 return ERR_SESSION_CLOSED_BY_REMOTE;
33} 31}
34 32
35} // namespace Kernel 33} // namespace Kernel
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index 2994fa0ac..c7db21eb2 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -31,8 +31,6 @@ ServerSession::~ServerSession() {
31 if (parent->port) { 31 if (parent->port) {
32 parent->port->ConnectionClosed(); 32 parent->port->ConnectionClosed();
33 } 33 }
34
35 parent->server = nullptr;
36} 34}
37 35
38ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, 36ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel,
@@ -46,11 +44,13 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern
46} 44}
47 45
48bool ServerSession::ShouldWait(const Thread* thread) const { 46bool ServerSession::ShouldWait(const Thread* thread) const {
49 // Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
50 if (parent->client == nullptr)
51 return false;
52 // Wait if we have no pending requests, or if we're currently handling a request. 47 // Wait if we have no pending requests, or if we're currently handling a request.
53 return pending_requesting_threads.empty() || currently_handling != nullptr; 48 if (auto client = parent->client.lock()) {
49 return pending_requesting_threads.empty() || currently_handling != nullptr;
50 }
51
52 // Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
53 return {};
54} 54}
55 55
56void ServerSession::Acquire(Thread* thread) { 56void ServerSession::Acquire(Thread* thread) {
@@ -192,9 +192,9 @@ ServerSession::SessionPair ServerSession::CreateSessionPair(KernelCore& kernel,
192 std::shared_ptr<ClientSession> client_session = std::make_shared<ClientSession>(kernel); 192 std::shared_ptr<ClientSession> client_session = std::make_shared<ClientSession>(kernel);
193 client_session->name = name + "_Client"; 193 client_session->name = name + "_Client";
194 194
195 std::shared_ptr<Session> parent(new Session); 195 std::shared_ptr<Session> parent = std::make_shared<Session>();
196 parent->client = client_session.get(); 196 parent->client = client_session;
197 parent->server = server_session.get(); 197 parent->server = server_session;
198 parent->port = std::move(port); 198 parent->port = std::move(port);
199 199
200 client_session->parent = parent; 200 client_session->parent = parent;
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index ea956813b..94395f9f5 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -20,8 +20,8 @@ class ServerSession;
20 */ 20 */
21class Session final { 21class Session final {
22public: 22public:
23 ClientSession* client = nullptr; ///< The client endpoint of the session. 23 std::weak_ptr<ClientSession> client; ///< The client endpoint of the session.
24 ServerSession* server = nullptr; ///< The server endpoint of the session. 24 std::weak_ptr<ServerSession> server; ///< The server endpoint of the session.
25 std::shared_ptr<ClientPort> port; ///< The port that this session is associated with (optional). 25 std::shared_ptr<ClientPort> port; ///< The port that this session is associated with (optional).
26}; 26};
27} // namespace Kernel 27} // namespace Kernel