[hle/service/am] make EventObserver use jthread() (#3971)

I don't remember why this wasn't done earlier, did I miss something or I purpousefully avoided this due to an issue?

Please test NO HANGS when opening/closing/playing

Signed-off-by: lizzie <[email protected]>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3971
Reviewed-by: MaranBr <[email protected]>
Reviewed-by: Maufeat <[email protected]>
This commit is contained in:
lizzie authored and crueter committed 2026-07-25 22:33:01 +02:00
1 parent eebb4bd91e
commit 6272f8ab24
2 files changed
+14 -20

No files matched your search

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