summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/service_thread.cpp44
1 files changed, 21 insertions, 23 deletions
diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp
index 1fc2edf52..1d8775504 100644
--- a/src/core/hle/kernel/service_thread.cpp
+++ b/src/core/hle/kernel/service_thread.cpp
@@ -2,6 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <functional> 4#include <functional>
5#include <map>
5#include <mutex> 6#include <mutex>
6#include <thread> 7#include <thread>
7#include <vector> 8#include <vector>
@@ -37,8 +38,7 @@ private:
37 38
38 std::jthread m_thread; 39 std::jthread m_thread;
39 std::mutex m_session_mutex; 40 std::mutex m_session_mutex;
40 std::vector<KServerSession*> m_sessions; 41 std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions;
41 std::vector<std::shared_ptr<SessionRequestManager>> m_managers;
42 KEvent* m_wakeup_event; 42 KEvent* m_wakeup_event;
43 KProcess* m_process; 43 KProcess* m_process;
44 std::atomic<bool> m_shutdown_requested; 44 std::atomic<bool> m_shutdown_requested;
@@ -51,19 +51,21 @@ void ServiceThread::Impl::WaitAndProcessImpl() {
51 std::vector<std::shared_ptr<SessionRequestManager>> managers; 51 std::vector<std::shared_ptr<SessionRequestManager>> managers;
52 52
53 { 53 {
54 // Lock to get the list. 54 // Lock to get the set.
55 std::scoped_lock lk{m_session_mutex}; 55 std::scoped_lock lk{m_session_mutex};
56 56
57 // Resize to the needed quantity. 57 // Reserve the needed quantity.
58 objs.resize(m_sessions.size() + 1); 58 objs.reserve(m_sessions.size() + 1);
59 managers.resize(m_managers.size()); 59 managers.reserve(m_sessions.size());
60 60
61 // Copy to our local list. 61 // Copy to our local list.
62 std::copy(m_sessions.begin(), m_sessions.end(), objs.begin()); 62 for (const auto& [session, manager] : m_sessions) {
63 std::copy(m_managers.begin(), m_managers.end(), managers.begin()); 63 objs.push_back(session);
64 managers.push_back(manager);
65 }
64 66
65 // Insert the wakeup event at the end. 67 // Insert the wakeup event at the end.
66 objs.back() = &m_wakeup_event->GetReadableEvent(); 68 objs.push_back(&m_wakeup_event->GetReadableEvent());
67 } 69 }
68 70
69 // Wait on the list of sessions. 71 // Wait on the list of sessions.
@@ -116,17 +118,11 @@ void ServiceThread::Impl::WaitAndProcessImpl() {
116void ServiceThread::Impl::SessionClosed(KServerSession* server_session, 118void ServiceThread::Impl::SessionClosed(KServerSession* server_session,
117 std::shared_ptr<SessionRequestManager> manager) { 119 std::shared_ptr<SessionRequestManager> manager) {
118 { 120 {
119 // Lock to get the list. 121 // Lock to get the set.
120 std::scoped_lock lk{m_session_mutex}; 122 std::scoped_lock lk{m_session_mutex};
121 123
122 // Get the index of the session. 124 // Erase the session.
123 const auto index = 125 ASSERT(m_sessions.erase(server_session) == 1);
124 std::find(m_sessions.begin(), m_sessions.end(), server_session) - m_sessions.begin();
125 ASSERT(index < static_cast<s64>(m_sessions.size()));
126
127 // Remove the session and its manager.
128 m_sessions.erase(m_sessions.begin() + index);
129 m_managers.erase(m_managers.begin() + index);
130 } 126 }
131 127
132 // Close our reference to the server session. 128 // Close our reference to the server session.
@@ -149,12 +145,11 @@ void ServiceThread::Impl::RegisterServerSession(KServerSession* server_session,
149 server_session->Open(); 145 server_session->Open();
150 146
151 { 147 {
152 // Lock to get the list. 148 // Lock to get the set.
153 std::scoped_lock lk{m_session_mutex}; 149 std::scoped_lock lk{m_session_mutex};
154 150
155 // Insert the session and manager. 151 // Insert the session and manager.
156 m_sessions.push_back(server_session); 152 m_sessions[server_session] = manager;
157 m_managers.push_back(manager);
158 } 153 }
159 154
160 // Signal the wakeup event. 155 // Signal the wakeup event.
@@ -171,10 +166,13 @@ ServiceThread::Impl::~Impl() {
171 m_session_mutex.lock(); 166 m_session_mutex.lock();
172 167
173 // Close all remaining sessions. 168 // Close all remaining sessions.
174 for (size_t i = 0; i < m_sessions.size(); i++) { 169 for (const auto& [server_session, manager] : m_sessions) {
175 m_sessions[i]->Close(); 170 server_session->Close();
176 } 171 }
177 172
173 // Destroy remaining managers.
174 m_sessions.clear();
175
178 // Close event. 176 // Close event.
179 m_wakeup_event->GetReadableEvent().Close(); 177 m_wakeup_event->GetReadableEvent().Close();
180 m_wakeup_event->Close(); 178 m_wakeup_event->Close();