diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp index 336010d987a7e7..73009fc783dc79 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.cpp +++ b/Userland/DevTools/HackStudio/HackStudioWidget.cpp @@ -849,7 +849,7 @@ void HackStudioWidget::initialize_debugger() m_disassembly_widget->update_state(*Debugger::the().session(), regs); HackStudioWidget::reveal_action_tab(*m_debug_info_widget); }); - Core::EventLoop::wake(); + Core::EventLoop::wake_current(); return Debugger::HasControlPassedToUser::Yes; }, @@ -859,7 +859,7 @@ void HackStudioWidget::initialize_debugger() if (m_current_editor_in_execution) m_current_editor_in_execution->editor().clear_execution_position(); }); - Core::EventLoop::wake(); + Core::EventLoop::wake_current(); }, [this]() { deferred_invoke([this] { @@ -879,7 +879,7 @@ void HackStudioWidget::initialize_debugger() HackStudioWidget::hide_action_tabs(); GUI::MessageBox::show(window(), "Program Exited", "Debugger", GUI::MessageBox::Type::Information); }); - Core::EventLoop::wake(); + Core::EventLoop::wake_current(); }); } diff --git a/Userland/Libraries/LibCore/EventLoop.cpp b/Userland/Libraries/LibCore/EventLoop.cpp index 2c2a9f6fe1197c..42734be04d0a81 100644 --- a/Userland/Libraries/LibCore/EventLoop.cpp +++ b/Userland/Libraries/LibCore/EventLoop.cpp @@ -302,7 +302,8 @@ class InspectorServerConnection : public Object { }; EventLoop::EventLoop([[maybe_unused]] MakeInspectable make_inspectable) - : m_private(make()) + : m_wake_pipe_fds(&s_wake_pipe_fds) + , m_private(make()) { #ifdef __serenity__ if (!s_global_initializers_ran) { @@ -487,11 +488,13 @@ size_t EventLoop::pump(WaitMode mode) return processed_events; } -void EventLoop::post_event(Object& receiver, NonnullOwnPtr&& event) +void EventLoop::post_event(Object& receiver, NonnullOwnPtr&& event, ShouldWake should_wake) { Threading::MutexLocker lock(m_private->lock); dbgln_if(EVENTLOOP_DEBUG, "Core::EventLoop::post_event: ({}) << receiver={}, event={}", m_queued_events.size(), receiver, event); m_queued_events.empend(receiver, move(event)); + if (should_wake == ShouldWake::Yes) + wake(); } SignalHandlers::SignalHandlers(int signo, void (*handle_signal)(int)) @@ -839,10 +842,16 @@ void EventLoop::unregister_notifier(Badge, Notifier& notifier) s_notifiers->remove(¬ifier); } +void EventLoop::wake_current() +{ + EventLoop::current().wake(); +} + void EventLoop::wake() { + dbgln_if(EVENTLOOP_DEBUG, "Core::EventLoop::wake()"); int wake_event = 0; - int nwritten = write(s_wake_pipe_fds[1], &wake_event, sizeof(wake_event)); + int nwritten = write((*m_wake_pipe_fds)[1], &wake_event, sizeof(wake_event)); if (nwritten < 0) { perror("EventLoop::wake: write"); VERIFY_NOT_REACHED(); diff --git a/Userland/Libraries/LibCore/EventLoop.h b/Userland/Libraries/LibCore/EventLoop.h index dbdaa146c11fc6..294be5bbec0a08 100644 --- a/Userland/Libraries/LibCore/EventLoop.h +++ b/Userland/Libraries/LibCore/EventLoop.h @@ -34,6 +34,11 @@ class EventLoop { Yes, }; + enum class ShouldWake { + No, + Yes + }; + explicit EventLoop(MakeInspectable = MakeInspectable::No); ~EventLoop(); static void initialize_wake_pipes(); @@ -51,7 +56,7 @@ class EventLoop { void spin_until(Function); - void post_event(Object& receiver, NonnullOwnPtr&&); + void post_event(Object& receiver, NonnullOwnPtr&&, ShouldWake = ShouldWake::No); template static decltype(auto) with_main_locked(Callback callback) @@ -79,7 +84,8 @@ class EventLoop { m_queued_events.extend(move(other.m_queued_events)); } - static void wake(); + static void wake_current(); + void wake(); static int register_signal(int signo, Function handler); static void unregister_signal(int handler_id); @@ -126,6 +132,9 @@ class EventLoop { static thread_local int s_wake_pipe_fds[2]; static thread_local bool s_wake_pipe_initialized; + // The wake pipe of this event loop needs to be accessible from other threads. + int (*m_wake_pipe_fds)[2]; + struct Private; NonnullOwnPtr m_private; }; diff --git a/Userland/Libraries/LibThreading/BackgroundAction.h b/Userland/Libraries/LibThreading/BackgroundAction.h index 39d2bf5f4b9b12..ee2b95dd802305 100644 --- a/Userland/Libraries/LibThreading/BackgroundAction.h +++ b/Userland/Libraries/LibThreading/BackgroundAction.h @@ -63,7 +63,7 @@ class BackgroundAction final : public Core::Object m_on_complete(m_result.release_value()); remove_from_parent(); }); - Core::EventLoop::wake(); + origin_event_loop->wake(); } else { this->remove_from_parent(); }