diff options
| author | 2019-11-25 18:17:08 -0500 | |
|---|---|---|
| committer | 2019-11-25 18:17:49 -0500 | |
| commit | f6b9b7910eb59cdc1e3aea9a1f1cb3d1cf8ae7f6 (patch) | |
| tree | 2514317ed0d0ada5de3a219bdd1f5baa635760dc /src | |
| parent | Merge pull request #3160 from DarkLordZach/opt-ea-clang-fmt (diff) | |
| download | yuzu-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.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/kernel/session.h | 4 |
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} {} | |||
| 16 | ClientSession::~ClientSession() { | 16 | ClientSession::~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 | ||
| 26 | ResultCode ClientSession::SendSyncRequest(Thread* thread) { | 24 | ResultCode 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 | ||
| 38 | ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, | 36 | ResultVal<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 | ||
| 48 | bool ServerSession::ShouldWait(const Thread* thread) const { | 46 | bool 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 | ||
| 56 | void ServerSession::Acquire(Thread* thread) { | 56 | void 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 | */ |
| 21 | class Session final { | 21 | class Session final { |
| 22 | public: | 22 | public: |
| 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 |