From b9642e4cf39968410d9d30b19e71cec66ae811d4 Mon Sep 17 00:00:00 2001 From: patrick96 Date: Sat, 11 Sep 2021 13:09:46 +0200 Subject: [PATCH] Move update events to eventloop We can now completely remove the eventqueue thread --- include/components/controller.hpp | 14 +--- include/events/types.hpp | 42 ----------- include/x11/background_manager.hpp | 1 - src/components/controller.cpp | 115 +++++++++++------------------ 4 files changed, 45 insertions(+), 127 deletions(-) delete mode 100644 include/events/types.hpp diff --git a/include/components/controller.hpp b/include/components/controller.hpp index 217fd560..c0f3bc37 100644 --- a/include/components/controller.hpp +++ b/include/components/controller.hpp @@ -10,7 +10,6 @@ #include "components/types.hpp" #include "events/signal_fwd.hpp" #include "events/signal_receiver.hpp" -#include "events/types.hpp" #include "settings.hpp" #include "utils/actions.hpp" #include "utils/file.hpp" @@ -51,9 +50,9 @@ class controller bool run(bool writeback, string snapshot_dst); - bool enqueue(event&& evt); void trigger_action(string&& input_data); void trigger_quit(bool reload); + void trigger_update(bool force); void stop(bool reload); @@ -66,7 +65,6 @@ class controller protected: void read_events(); - void process_eventqueue(); void process_inputdata(); bool process_update(bool force); @@ -121,11 +119,6 @@ class controller */ bool m_writeback{false}; - /** - * \brief Internal event queue - */ - moodycamel::BlockingConcurrentQueue m_queue; - /** * \brief Loaded modules */ @@ -151,11 +144,6 @@ class controller */ string m_inputdata; - /** - * \brief Thread for the eventqueue loop - */ - std::thread m_event_thread; - /** * \brief Misc threads */ diff --git a/include/events/types.hpp b/include/events/types.hpp deleted file mode 100644 index 8e5cc831..00000000 --- a/include/events/types.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include - -#include "common.hpp" - -POLYBAR_NS - -enum class event_type { - NONE = 0, - UPDATE, -}; - -struct event { - int type{0}; - bool flag{false}; -}; - -namespace { - inline bool operator==(int id, event_type type) { - return id == static_cast(type); - } - inline bool operator!=(int id, event_type type) { - return !(id == static_cast(type)); - } - - /** - * Create NONE event - */ - inline event make_none_evt() { - return event{static_cast(event_type::NONE)}; - } - - /** - * Create UPDATE event - */ - inline event make_update_evt(bool force = false) { - return event{static_cast(event_type::UPDATE), force}; - } -} - -POLYBAR_NS_END diff --git a/include/x11/background_manager.hpp b/include/x11/background_manager.hpp index e5de8bd8..8e6a734e 100644 --- a/include/x11/background_manager.hpp +++ b/include/x11/background_manager.hpp @@ -6,7 +6,6 @@ #include "common.hpp" #include "events/signal_fwd.hpp" #include "events/signal_receiver.hpp" -#include "events/types.hpp" #include "x11/extensions/fwd.hpp" #include "x11/types.hpp" diff --git a/src/components/controller.cpp b/src/components/controller.cpp index 35cde3e5..470f93e8 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -31,6 +31,10 @@ POLYBAR_NS sig_atomic_t g_reload{0}; sig_atomic_t g_terminate{0}; +// TODO pass this information in a better way +sig_atomic_t g_update{0}; +sig_atomic_t g_force_update{0}; + /** * Build controller instance */ @@ -57,6 +61,7 @@ controller::controller(connection& conn, signal_emitter& emitter, const logger& "remove it from your config"); } + // TODO deprecate both m_swallow_limit = m_conf.deprecated("settings", "eventqueue-swallow", "throttle-output", m_swallow_limit); m_swallow_update = m_conf.deprecated("settings", "eventqueue-swallow-time", "throttle-output-for", m_swallow_update); @@ -129,34 +134,14 @@ bool controller::run(bool writeback, string snapshot_dst) { } m_connection.flush(); - m_event_thread = thread(&controller::process_eventqueue, this); read_events(); - if (m_event_thread.joinable()) { - m_log.info("Joining event thread"); - m_event_thread.join(); - } - m_log.notice("Termination signal received, shutting down..."); return !g_reload; } -/** - * Enqueue event - */ -bool controller::enqueue(event&& evt) { - if (!m_process_events) { - return false; - } - if (!m_queue.enqueue(forward(evt))) { - m_log.warn("Failed to enqueue event"); - return false; - } - return true; -} - /** * Enqueue input data */ @@ -172,9 +157,23 @@ void controller::trigger_action(string&& input_data) { void controller::trigger_quit(bool reload) { g_terminate = 1; g_reload = reload; + // TODO create function for this UV(uv_async_send, m_notifier.get()); } +void controller::trigger_update(bool force) { + if (force) { + g_force_update = 1; + } else { + g_update = 1; + } + + // TODO this isn't really safe + if (m_notifier) { + UV(uv_async_send, m_notifier.get()); + } +} + void controller::stop(bool reload) { g_terminate = 1; g_reload = reload; @@ -237,6 +236,15 @@ void controller::notifier_handler() { if (!m_inputdata.empty()) { process_inputdata(); } + + if (g_force_update) { + process_update(true); + } else if (g_update) { + process_update(false); + } + + g_update = 0; + g_force_update = 0; } static void ipc_alloc_cb(uv_handle_t*, size_t, uv_buf_t* buf) { @@ -273,6 +281,15 @@ static void notifier_cb_wrapper(uv_async_t *handle) { void controller::read_events() { m_log.info("Entering event loop (thread-id=%lu)", this_thread::get_id()); + if (!m_writeback) { + m_sig.emit(signals::eventqueue::start{}); + } else { + // bypass the start eventqueue signal + m_sig.emit(signals::ui::ready{}); + } + + process_update(true); + auto ipc_handle = std::unique_ptr(nullptr); try { @@ -309,56 +326,11 @@ void controller::read_events() { stop(false); } - // Notify event queue so that it stops - enqueue(make_none_evt()); - m_log.info("Eventloop finished"); eloop.reset(); } -/** - * Eventqueue worker loop - */ -void controller::process_eventqueue() { - m_log.info("Eventqueue worker (thread-id=%lu)", this_thread::get_id()); - if (!m_writeback) { - m_sig.emit(signals::eventqueue::start{}); - } else { - // bypass the start eventqueue signal - m_sig.emit(signals::ui::ready{}); - } - - while (!g_terminate) { - event evt{}; - m_queue.wait_dequeue(evt); - - if (g_terminate) { - break; - } else if (evt.type == event_type::UPDATE && evt.flag) { - process_update(true); - } else { - event next{}; - size_t swallowed{0}; - while (swallowed++ < m_swallow_limit && m_queue.wait_dequeue_timed(next, m_swallow_update)) { - if (evt.type != next.type) { - enqueue(move(next)); - break; - } else { - m_log.trace_x("controller: Swallowing event within timeframe"); - evt = next; - } - } - - if (evt.type == event_type::UPDATE) { - process_update(evt.flag); - } else { - m_log.warn("Unknown event type for enqueued event (%d)", evt.type); - } - } - } -} - /** * Tries to match the given command to a legacy action string and sends the * appropriate new action (and data) to the right module if possible. @@ -693,14 +665,16 @@ size_t controller::setup_modules(alignment align) { * Process broadcast events */ bool controller::on(const signals::eventqueue::notify_change&) { - return enqueue(make_update_evt(false)); + trigger_update(false); + return true; } /** * Process forced broadcast events */ bool controller::on(const signals::eventqueue::notify_forcechange&) { - return enqueue(make_update_evt(true)); + trigger_update(true); + return true; } /** @@ -738,13 +712,13 @@ bool controller::on(const signals::eventqueue::check_state&) { */ bool controller::on(const signals::ui::ready&) { m_process_events = true; - enqueue(make_update_evt(true)); + trigger_update(true); if (!m_snapshot_dst.empty()) { m_threads.emplace_back(thread([&] { this_thread::sleep_for(3s); m_sig.emit(signals::ui::request_snapshot{move(m_snapshot_dst)}); - enqueue(make_update_evt(true)); + trigger_update(true); })); } @@ -830,8 +804,7 @@ bool controller::on(const signals::ipc::hook& evt) { } bool controller::on(const signals::ui::update_background&) { - enqueue(make_update_evt(true)); - + trigger_update(true); return false; }