diff --git a/src/core/hle/service/am/event_observer.cpp b/src/core/hle/service/am/event_observer.cpp index 32cb35ee30..520000b64f 100644 --- a/src/core/hle/service/am/event_observer.cpp +++ b/src/core/hle/service/am/event_observer.cpp @@ -26,13 +26,12 @@ EventObserver::EventObserver(Core::System& system, WindowSystem& window_system) m_window_system.SetEventObserver(this); m_wakeup_holder.SetUserData(static_cast(UserDataTag::WakeupEvent)); m_wakeup_holder.LinkToMultiWait(std::addressof(m_multi_wait)); - m_thread = std::thread([this] { + m_thread = std::jthread([this](std::stop_token stop_token) { Common::SetCurrentThreadName("am:EventObserver"); - while (true) { - auto* signaled_holder = this->WaitSignaled(); - if (!signaled_holder) { + while (!stop_token.stop_requested()) { + auto* signaled_holder = this->WaitSignaled(stop_token); + if (!signaled_holder) break; - } this->Process(signaled_holder); } }); @@ -40,9 +39,12 @@ EventObserver::EventObserver(Core::System& system, WindowSystem& window_system) EventObserver::~EventObserver() { // Signal thread and wait for processing to finish. - m_stop_source.request_stop(); - m_wakeup_event.Signal(m_system.Kernel()); - m_thread.join(); + if (m_thread.joinable()) { + // Signal thread and wait for processing to finish. + m_thread.request_stop(); + m_wakeup_event.Signal(m_system.Kernel()); + m_thread.join(); + } // Free remaining owned sessions. auto it = m_process_holder_list.begin(); @@ -88,12 +90,12 @@ void EventObserver::LinkDeferred() { m_multi_wait.MoveAll(std::addressof(m_deferred_wait_list)); } -MultiWaitHolder* EventObserver::WaitSignaled() { +MultiWaitHolder* EventObserver::WaitSignaled(std::stop_token stop_token) { while (true) { this->LinkDeferred(); // If we're done, return before we start waiting. - if (m_stop_source.stop_requested()) { + if (stop_token.stop_requested()) { return nullptr; } @@ -131,7 +133,6 @@ void EventObserver::OnProcessEvent(ProcessHolder* holder) { // Check process state. auto& applet = holder->GetApplet(); auto& process = holder->GetProcess(); - { std::scoped_lock lk{m_lock, applet.lock}; if (process.IsTerminated()) { @@ -156,7 +157,6 @@ void EventObserver::OnProcessEvent(ProcessHolder* holder) { void EventObserver::DestroyAppletProcessHolderLocked(ProcessHolder* holder) { // Remove from owned list. m_process_holder_list.erase(m_process_holder_list.iterator_to(*holder)); - // Destroy and free. delete holder; } diff --git a/src/core/hle/service/am/event_observer.h b/src/core/hle/service/am/event_observer.h index a0fa13f823..c66eb711c8 100644 --- a/src/core/hle/service/am/event_observer.h +++ b/src/core/hle/service/am/event_observer.h @@ -32,19 +32,14 @@ public: private: void LinkDeferred(); - MultiWaitHolder* WaitSignaled(); + MultiWaitHolder* WaitSignaled(std::stop_token stop_token); void Process(MultiWaitHolder* holder); bool WaitAndProcessImpl(); void LoopProcess(); - -private: void OnWakeupEvent(MultiWaitHolder* holder); void OnProcessEvent(ProcessHolder* holder); - -private: void DestroyAppletProcessHolderLocked(ProcessHolder* holder); -private: // System reference and context. Core::System& m_system; KernelHelpers::ServiceContext m_context; @@ -67,8 +62,7 @@ private: MultiWait m_deferred_wait_list; // Processing thread. - std::thread m_thread{}; - std::stop_source m_stop_source{}; + std::jthread m_thread{}; }; } // namespace Service::AM