diff options
| -rw-r--r-- | src/core/hle/kernel/service_thread.cpp | 44 |
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() { | |||
| 116 | void ServiceThread::Impl::SessionClosed(KServerSession* server_session, | 118 | void 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(); |