From ce63305c1d62ed5bb8c8dfe3272ad49be04e9009 Mon Sep 17 00:00:00 2001
From: patrick96
Date: Sat, 11 Sep 2021 15:39:22 +0200
Subject: [PATCH] Better way to notify controller
---
include/components/controller.hpp | 31 ++++++++++++---
src/components/controller.cpp | 64 ++++++++++++++-----------------
2 files changed, 54 insertions(+), 41 deletions(-)
diff --git a/include/components/controller.hpp b/include/components/controller.hpp
index 646f1057..bcf9741a 100644
--- a/include/components/controller.hpp
+++ b/include/components/controller.hpp
@@ -64,7 +64,7 @@ class controller : public signal_receiver m_notifier{nullptr};
+ /**
+ * Notification data for the controller.
+ *
+ * Triggers, potentially from other threads, update this structure and notify the controller through m_notifier.
+ */
+ notifications_t m_notifications{};
+
+ /**
+ * \brief Protected m_notifications.
+ *
+ * All accesses to m_notifications must hold this mutex.
+ */
+ std::mutex m_notification_mutex{};
+
/**
* \brief Destination path of generated snapshot
*/
@@ -119,11 +143,6 @@ class controller : public signal_receiver(input_data);
+ std::unique_lock guard(m_notification_mutex);
+
+ if (m_notifications.inputdata.empty()) {
+ m_notifications.inputdata = std::forward(input_data);
+ // TODO create function for this
UV(uv_async_send, m_notifier.get());
+ } else {
+ m_log.trace("controller: Swallowing input event (pending data)");
}
}
void controller::trigger_quit(bool reload) {
- g_terminate = 1;
- g_reload = reload;
+ std::unique_lock guard(m_notification_mutex);
+ m_notifications.quit = true;
+ m_notifications.reload = m_notifications.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;
- }
+ std::unique_lock guard(m_notification_mutex);
+ m_notifications.update = true;
+ m_notifications.force_update = m_notifications.force_update || force;
// TODO this isn't really safe
if (m_notifier) {
+ // TODO create function for this
UV(uv_async_send, m_notifier.get());
}
}
void controller::stop(bool reload) {
- g_terminate = 1;
g_reload = reload;
eloop->stop();
}
@@ -220,23 +217,27 @@ void controller::confwatch_handler(const char* filename, int, int) {
}
void controller::notifier_handler() {
- if (g_terminate) {
+ notifications_t data{};
+
+ {
+ std::unique_lock guard(m_notification_mutex);
+ std::swap(m_notifications, data);
+ }
+
+ if (data.quit) {
+ // TODO store this in the instance
+ g_reload = data.reload;
eloop->stop();
return;
}
- if (!m_inputdata.empty()) {
- process_inputdata();
+ if (!data.inputdata.empty()) {
+ process_inputdata(std::move(data.inputdata));
}
- if (g_force_update) {
- process_update(true);
- } else if (g_update) {
- process_update(false);
+ if (data.update) {
+ process_update(data.force_update);
}
-
- g_update = 0;
- g_force_update = 0;
}
static void ipc_alloc_cb(uv_handle_t*, size_t, uv_buf_t* buf) {
@@ -484,14 +485,7 @@ bool controller::forward_action(const actions_util::action& action_triple) {
/**
* Process stored input data
*/
-void controller::process_inputdata() {
- if (m_inputdata.empty()) {
- return;
- }
-
- const string cmd = std::move(m_inputdata);
- m_inputdata = string{};
-
+void controller::process_inputdata(string&& cmd) {
m_log.trace("controller: Processing inputdata: %s", cmd);
// Every command that starts with '#' is considered an action string.