From 3cc17a0e5707e9eaab583525e15c8d32dd9f4777 Mon Sep 17 00:00:00 2001
From: patrick96
Date: Tue, 2 Mar 2021 00:00:24 +0100
Subject: [PATCH] Move signal handling to eventloop class
---
include/components/controller.hpp | 4 +++-
include/components/eventloop.hpp | 40 ++++++++++++++++++++++++++++++-
include/utils/file.hpp | 2 +-
src/components/controller.cpp | 22 +++++++----------
src/components/eventloop.cpp | 20 ++++++++++++++++
src/components/ipc.cpp | 6 +----
src/modules/xwindow.cpp | 1 +
src/utils/file.cpp | 2 +-
8 files changed, 74 insertions(+), 23 deletions(-)
diff --git a/include/components/controller.hpp b/include/components/controller.hpp
index 99f25942..023ebad0 100644
--- a/include/components/controller.hpp
+++ b/include/components/controller.hpp
@@ -53,6 +53,8 @@ class controller
bool enqueue(event&& evt);
bool enqueue(string&& input_data);
+ void signal_handler(int signum);
+
void conn_cb(int status, int events);
void ipc_cb(string buf);
@@ -88,7 +90,7 @@ class controller
unique_ptr m_ipc;
unique_ptr m_confwatch;
- eventloop eloop;
+ std::unique_ptr eloop;
/**
* \brief State flag
diff --git a/include/components/eventloop.hpp b/include/components/eventloop.hpp
index bffe88e1..dcdd9517 100644
--- a/include/components/eventloop.hpp
+++ b/include/components/eventloop.hpp
@@ -6,6 +6,30 @@
POLYBAR_NS
+template
+struct cb_helper {
+ std::function func;
+
+ static void callback(H* context, Args... args) {
+ const auto unpackedThis = static_cast(context->data);
+ return unpackedThis->func(std::forward(args)...);
+ }
+};
+
+struct SignalHandle {
+ SignalHandle(uv_loop_t* loop, std::function fun) {
+ handle = std::make_unique();
+ // TODO handle return value
+ uv_signal_init(loop, handle.get());
+ cb = cb_helper{fun};
+
+ handle->data = &cb;
+ };
+
+ std::unique_ptr handle;
+ cb_helper cb;
+};
+
class eventloop {
public:
eventloop();
@@ -16,14 +40,28 @@ class eventloop {
void stop();
/**
- * TODO remove
+ * TODO make protected
*/
uv_loop_t* get() const {
return m_loop.get();
}
+ void signal_handler(int signum, std::function fun) {
+ auto handle = std::make_unique(get(), fun);
+ uv_signal_start(handle->handle.get(), &handle->cb.callback, signum);
+ m_sig_handles.push_back(std::move(handle));
+ }
+
+ protected:
+ template
+ static void generic_cb(H* handle, Args&&... args) {
+ (static_cast(handle->data).*F)(std::forward(args)...);
+ }
+
private:
std::unique_ptr m_loop{nullptr};
+
+ vector> m_sig_handles;
};
POLYBAR_NS_END
diff --git a/include/utils/file.hpp b/include/utils/file.hpp
index 0e062936..ebbf1921 100644
--- a/include/utils/file.hpp
+++ b/include/utils/file.hpp
@@ -29,7 +29,7 @@ class file_ptr {
class file_descriptor {
public:
- explicit file_descriptor(const string& path, int flags = 0);
+ explicit file_descriptor(const string& path, int flags = 0, bool autoclose = true);
explicit file_descriptor(int fd, bool autoclose = true);
~file_descriptor();
diff --git a/src/components/controller.cpp b/src/components/controller.cpp
index 21c8ee88..8cbf9073 100644
--- a/src/components/controller.cpp
+++ b/src/components/controller.cpp
@@ -134,7 +134,6 @@ bool controller::run(bool writeback, string snapshot_dst) {
read_events();
if (m_event_thread.joinable()) {
- enqueue(make_quit_evt(static_cast(g_reload)));
m_event_thread.join();
}
@@ -179,7 +178,7 @@ void controller::conn_cb(int, int) {
if (m_connection.connection_has_error()) {
g_terminate = 1;
g_reload = 0;
- eloop.stop();
+ eloop->stop();
return;
}
@@ -204,10 +203,10 @@ static void conn_cb_wrapper(uv_poll_t* handle, int status, int events) {
static_cast(handle->data)->conn_cb(status, events);
}
-static void signal_cb_wrapper(uv_signal_t* handle, int signum) {
+void controller::signal_handler(int signum) {
g_terminate = 1;
g_reload = (signum == SIGUSR1);
- static_cast(handle->loop->data)->stop();
+ eloop->stop();
}
static void confwatch_cb_wrapper(uv_fs_event_t* handle, const char* fname, int, int) {
@@ -249,7 +248,8 @@ static void ipc_read_cb_wrapper(uv_stream_t* stream, ssize_t nread, const uv_buf
void controller::read_events() {
m_log.info("Entering event loop (thread-id=%lu)", this_thread::get_id());
- auto loop = eloop.get();
+ eloop = std::make_unique();
+ auto loop = eloop->get();
auto conn_handle = std::make_unique();
uv_poll_init(loop, conn_handle.get(), m_connection.get_file_descriptor());
@@ -257,15 +257,8 @@ void controller::read_events() {
uv_poll_start(conn_handle.get(), UV_READABLE, conn_cb_wrapper);
- std::vector> handles;
-
for (auto s : {SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGALRM}) {
- auto signal_handle = std::make_unique();
- uv_signal_init(loop, signal_handle.get());
- signal_handle->data = this;
-
- uv_signal_start(signal_handle.get(), signal_cb_wrapper, s);
- handles.push_back(std::move(signal_handle));
+ eloop->signal_handler(s, [this](int signum) { signal_handler(signum); });
}
auto conf_handle = std::unique_ptr(nullptr);
@@ -288,7 +281,8 @@ void controller::read_events() {
uv_read_start((uv_stream_t*)ipc_handle.get(), ipc_alloc_cb, ipc_read_cb_wrapper);
}
- eloop.run();
+ eloop->run();
+ eloop.reset();
}
/**
diff --git a/src/components/eventloop.cpp b/src/components/eventloop.cpp
index 99e2e35e..d3d4a1bc 100644
--- a/src/components/eventloop.cpp
+++ b/src/components/eventloop.cpp
@@ -10,10 +10,30 @@ eventloop::eventloop() {
m_loop->data = this;
}
+static void close_walk_cb(uv_handle_t* handle, void*) {
+ if (!uv_is_closing(handle)) {
+ uv_close(handle, nullptr);
+ }
+}
+
+/**
+ * Completely closes everything in the loop.
+ *
+ * After this function returns, uv_loop_close can be called.
+ */
+static void close_loop(uv_loop_t* loop) {
+ uv_walk(loop, close_walk_cb, nullptr);
+ uv_run(loop, UV_RUN_DEFAULT);
+ // TODO handle return value
+}
+
eventloop::~eventloop() {
if (m_loop) {
+ close_loop(m_loop.get());
uv_loop_close(m_loop.get());
// TODO handle return value
+
+ m_loop.reset();
}
}
diff --git a/src/components/ipc.cpp b/src/components/ipc.cpp
index 17473815..7487a910 100644
--- a/src/components/ipc.cpp
+++ b/src/components/ipc.cpp
@@ -34,15 +34,13 @@ ipc::ipc(signal_emitter& emitter, const logger& logger) : m_sig(emitter), m_log(
}
m_log.info("Created ipc channel at: %s", m_path);
- m_fd = file_util::make_file_descriptor(m_path, O_RDONLY | O_NONBLOCK);
+ m_fd = file_util::make_file_descriptor(m_path, O_RDONLY | O_NONBLOCK, false);
}
/**
* Deconstruct ipc handler
*/
ipc::~ipc() {
- m_fd.reset();
-
if (!m_path.empty()) {
m_log.trace("ipc: Removing file handle");
unlink(m_path.c_str());
@@ -66,8 +64,6 @@ void ipc::receive_message(string buf) {
} else if (!payload.empty()) {
m_log.warn("Received unknown ipc message: (payload=%s)", payload);
}
-
- /* m_fd = file_util::make_file_descriptor(m_path, O_RDONLY | O_NONBLOCK); */
}
/**
diff --git a/src/modules/xwindow.cpp b/src/modules/xwindow.cpp
index 010750c1..a6eccef5 100644
--- a/src/modules/xwindow.cpp
+++ b/src/modules/xwindow.cpp
@@ -86,6 +86,7 @@ namespace modules {
* Handler for XCB_PROPERTY_NOTIFY events
*/
void xwindow_module::handle(const evt::property_notify& evt) {
+ m_log.notice("%s: handle Thread id: %i", name(), concurrency_util::thread_id(this_thread::get_id()));
if (evt->atom == _NET_ACTIVE_WINDOW) {
update(true);
} else if (evt->atom == _NET_CURRENT_DESKTOP) {
diff --git a/src/utils/file.cpp b/src/utils/file.cpp
index 83f51ddb..d8303054 100644
--- a/src/utils/file.cpp
+++ b/src/utils/file.cpp
@@ -52,7 +52,7 @@ file_ptr::operator int() const {
// }}}
// implementation of file_descriptor {{{
-file_descriptor::file_descriptor(const string& path, int flags) {
+file_descriptor::file_descriptor(const string& path, int flags, bool autoclose) : m_autoclose(autoclose) {
if ((m_fd = open(path.c_str(), flags)) == -1) {
throw system_error("Failed to open file descriptor");
}