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;
}