summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorkleines Filmröllchen <filmroellchen@serenityos.org>2022-02-11 16:57:10 +0100
committerAndreas Kling <kling@serenityos.org>2022-02-13 23:06:53 +0100
commit704bb361bbb40f01259d963ae5d20cd4b9c51482 (patch)
treed2deea719854c76d6933571cca392332d1e8bb72 /Userland
parent716a3429fa2693bc512b19d25e524c34b58049c5 (diff)
downloadserenity-704bb361bbb40f01259d963ae5d20cd4b9c51482.zip
LibCore: Allow event loops on other threads to wake up
Because the wake pipe is thread-local, it was previously not possible to wake an event loop across a thread. Therefore, this commit rearchitects event loop waking by making the wake function a member of the event loop itself and having it keep a pointer to its thread's wake pipe. The global wake() function calls wake on the current thread's event loop. This also fixes a bug in BackgroundAction: it should wake the event loop it was created on, instead of the current thread's event loop.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/DevTools/HackStudio/HackStudioWidget.cpp6
-rw-r--r--Userland/Libraries/LibCore/EventLoop.cpp15
-rw-r--r--Userland/Libraries/LibCore/EventLoop.h13
-rw-r--r--Userland/Libraries/LibThreading/BackgroundAction.h2
4 files changed, 27 insertions, 9 deletions
diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp
index 336010d987..73009fc783 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 2c2a9f6fe1..42734be04d 100644
--- a/Userland/Libraries/LibCore/EventLoop.cpp
+++ b/Userland/Libraries/LibCore/EventLoop.cpp
@@ -302,7 +302,8 @@ private:
};
EventLoop::EventLoop([[maybe_unused]] MakeInspectable make_inspectable)
- : m_private(make<Private>())
+ : m_wake_pipe_fds(&s_wake_pipe_fds)
+ , m_private(make<Private>())
{
#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>&& event)
+void EventLoop::post_event(Object& receiver, NonnullOwnPtr<Event>&& 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& notifier)
s_notifiers->remove(&notifier);
}
+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 dbdaa146c1..294be5bbec 100644
--- a/Userland/Libraries/LibCore/EventLoop.h
+++ b/Userland/Libraries/LibCore/EventLoop.h
@@ -34,6 +34,11 @@ public:
Yes,
};
+ enum class ShouldWake {
+ No,
+ Yes
+ };
+
explicit EventLoop(MakeInspectable = MakeInspectable::No);
~EventLoop();
static void initialize_wake_pipes();
@@ -51,7 +56,7 @@ public:
void spin_until(Function<bool()>);
- void post_event(Object& receiver, NonnullOwnPtr<Event>&&);
+ void post_event(Object& receiver, NonnullOwnPtr<Event>&&, ShouldWake = ShouldWake::No);
template<typename Callback>
static decltype(auto) with_main_locked(Callback callback)
@@ -79,7 +84,8 @@ public:
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<void(int)> handler);
static void unregister_signal(int handler_id);
@@ -126,6 +132,9 @@ private:
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<Private> m_private;
};
diff --git a/Userland/Libraries/LibThreading/BackgroundAction.h b/Userland/Libraries/LibThreading/BackgroundAction.h
index 39d2bf5f4b..ee2b95dd80 100644
--- a/Userland/Libraries/LibThreading/BackgroundAction.h
+++ b/Userland/Libraries/LibThreading/BackgroundAction.h
@@ -63,7 +63,7 @@ private:
m_on_complete(m_result.release_value());
remove_from_parent();
});
- Core::EventLoop::wake();
+ origin_event_loop->wake();
} else {
this->remove_from_parent();
}