From 895c1a6b516ea69fa092203bec0bdfbded41ddce Mon Sep 17 00:00:00 2001
From: patrick96
Date: Mon, 13 Sep 2021 18:16:00 +0200
Subject: [PATCH] Handle fs_event and poll errors in handle wrapper
---
include/components/controller.hpp | 4 +--
include/components/eventloop.hpp | 23 +++++++++++---
include/components/ipc.hpp | 10 +-----
src/components/controller.cpp | 22 ++++++-------
src/components/eventloop.cpp | 53 +++++++++++++++++++++++--------
src/components/ipc.cpp | 7 ++++
6 files changed, 77 insertions(+), 42 deletions(-)
diff --git a/include/components/controller.hpp b/include/components/controller.hpp
index 81623866..30624edf 100644
--- a/include/components/controller.hpp
+++ b/include/components/controller.hpp
@@ -56,8 +56,8 @@ class controller : public signal_receiver {
};
struct PollHandle : public UVHandle {
- PollHandle(uv_loop_t* loop, int fd, std::function fun);
+ PollHandle(uv_loop_t* loop, int fd, std::function fun, std::function err_cb);
void start(int events);
+ void poll_cb(int status, int events);
+
+ std::function func;
+ std::function err_cb;
};
struct FSEventHandle : public UVHandle {
- FSEventHandle(uv_loop_t* loop, std::function fun);
+ FSEventHandle(uv_loop_t* loop, std::function fun, std::function err_cb);
void start(const string& path);
+ void fs_event_cb(const char* path, int events, int status);
+
+ std::function func;
+ std::function err_cb;
};
struct PipeHandle : public UVHandleGeneric {
@@ -113,8 +125,9 @@ class eventloop {
void run();
void stop();
void signal_handler(int signum, std::function fun);
- void poll_handler(int events, int fd, std::function fun);
- void fs_event_handler(const string& path, std::function fun);
+ void poll_handler(int events, int fd, std::function fun, std::function err_cb);
+ void fs_event_handler(
+ const string& path, std::function fun, std::function err_cb);
void pipe_handle(int fd, std::function fun, std::function eof_cb);
void timer_handle(uint64_t timeout, uint64_t repeat, std::function fun);
AsyncHandle_t async_handle(std::function fun);
diff --git a/include/components/ipc.hpp b/include/components/ipc.hpp
index 27bcdff9..f6082371 100644
--- a/include/components/ipc.hpp
+++ b/include/components/ipc.hpp
@@ -8,16 +8,8 @@
POLYBAR_NS
-class file_descriptor;
-class logger;
class signal_emitter;
-
-/**
- * Message types
- */
-static constexpr const char* ipc_command_prefix{"cmd:"};
-static constexpr const char* ipc_hook_prefix{"hook:"};
-static constexpr const char* ipc_action_prefix{"action:"};
+class logger;
/**
* Component used for inter-process communication.
diff --git a/src/components/controller.cpp b/src/components/controller.cpp
index 99211b13..68a8cc0b 100644
--- a/src/components/controller.cpp
+++ b/src/components/controller.cpp
@@ -130,7 +130,7 @@ void controller::trigger_action(string&& input_data) {
std::unique_lock guard(m_notification_mutex);
if (m_notifications.inputdata.empty()) {
- m_notifications.inputdata = std::forward(input_data);
+ m_notifications.inputdata = std::move(input_data);
trigger_notification();
} else {
m_log.trace("controller: Swallowing input event (pending data)");
@@ -163,13 +163,7 @@ void controller::stop(bool reload) {
eloop->stop();
}
-void controller::conn_cb(int status, int) {
- if (status < 0) {
- // TODO Should we stop polling here?
- m_log.err("libuv error while polling X connection: %s", uv_strerror(status));
- return;
- }
-
+void controller::conn_cb(uv_poll_event) {
int xcb_error = m_connection.connection_has_error();
if ((xcb_error = m_connection.connection_has_error()) > 0) {
m_log.err("X connection error, terminating... (what: %s)", m_connection.error_str(xcb_error));
@@ -200,7 +194,7 @@ void controller::signal_handler(int signum) {
stop(signum == SIGUSR1);
}
-void controller::confwatch_handler(const char* filename, int, int) {
+void controller::confwatch_handler(const char* filename, uv_fs_event) {
m_log.notice("Watched config file changed %s", filename);
stop(true);
}
@@ -247,15 +241,19 @@ void controller::read_events(bool confwatch) {
eloop = std::make_unique();
eloop->poll_handler(
- UV_READABLE, m_connection.get_file_descriptor(), [this](int status, int events) { conn_cb(status, events); });
+ UV_READABLE, m_connection.get_file_descriptor(), [this](uv_poll_event events) { conn_cb(events); },
+ [](int status) { throw runtime_error("libuv error while polling X connection: "s + uv_strerror(status)); });
for (auto s : {SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGALRM}) {
eloop->signal_handler(s, [this](int signum) { signal_handler(signum); });
}
if (confwatch) {
- eloop->fs_event_handler(m_conf.filepath(),
- [this](const char* path, int events, int status) { confwatch_handler(path, events, status); });
+ eloop->fs_event_handler(
+ m_conf.filepath(), [this](const char* path, uv_fs_event events) { confwatch_handler(path, events); },
+ [this](int status) {
+ m_log.err("libuv error while watching config file for changes: %s", uv_strerror(status));
+ });
}
if (m_ipc) {
diff --git a/src/components/eventloop.cpp b/src/components/eventloop.cpp
index 57292ee0..09a302da 100644
--- a/src/components/eventloop.cpp
+++ b/src/components/eventloop.cpp
@@ -13,22 +13,22 @@ POLYBAR_NS
void close_callback(uv_handle_t* handle) {
switch (handle->type) {
case UV_ASYNC:
- static_cast(handle->data)->close();
+ static_cast(handle->data)->cleanup_resources();
break;
case UV_FS_EVENT:
- static_cast(handle->data)->close();
+ static_cast(handle->data)->cleanup_resources();
break;
case UV_POLL:
- static_cast(handle->data)->close();
+ static_cast(handle->data)->cleanup_resources();
break;
case UV_TIMER:
- static_cast(handle->data)->close();
+ static_cast(handle->data)->cleanup_resources();
break;
case UV_SIGNAL:
- static_cast(handle->data)->close();
+ static_cast(handle->data)->cleanup_resources();
break;
case UV_NAMED_PIPE:
- static_cast(handle->data)->close();
+ static_cast(handle->data)->cleanup_resources();
break;
default:
assert(false);
@@ -51,25 +51,48 @@ void SignalHandle::start(int signum) {
// }}}
// PollHandle {{{
-// TODO wrap callback and handle status
-PollHandle::PollHandle(uv_loop_t* loop, int fd, std::function fun) : UVHandle(fun) {
+PollHandle::PollHandle(uv_loop_t* loop, int fd, std::function fun, std::function err_cb)
+ : UVHandle([this](int status, int events) { poll_cb(status, events); }), func(fun), err_cb(err_cb) {
UV(uv_poll_init, loop, handle, fd);
}
void PollHandle::start(int events) {
UV(uv_poll_start, handle, events, callback);
}
+
+void PollHandle::poll_cb(int status, int events) {
+ if (status < 0) {
+ close();
+ err_cb(status);
+ return;
+ }
+
+ func((uv_poll_event)events);
+}
// }}}
// FSEventHandle {{{
-// TODO wrap callback and handle status
-FSEventHandle::FSEventHandle(uv_loop_t* loop, std::function fun) : UVHandle(fun) {
+FSEventHandle::FSEventHandle(
+ uv_loop_t* loop, std::function fun, std::function err_cb)
+ : UVHandle([this](const char* path, int events, int status) { fs_event_cb(path, events, status); })
+ , func(fun)
+ , err_cb(err_cb) {
UV(uv_fs_event_init, loop, handle);
}
void FSEventHandle::start(const string& path) {
UV(uv_fs_event_start, handle, callback, path.c_str(), 0);
}
+
+void FSEventHandle::fs_event_cb(const char* path, int events, int status) {
+ if (status < 0) {
+ close();
+ err_cb(status);
+ return;
+ }
+
+ func(path, (uv_fs_event)events);
+}
// }}}
// PipeHandle {{{
@@ -182,13 +205,15 @@ void eventloop::signal_handler(int signum, std::function fun) {
m_sig_handles.back()->start(signum);
}
-void eventloop::poll_handler(int events, int fd, std::function fun) {
- m_poll_handles.emplace_back(std::make_unique(get(), fd, fun));
+void eventloop::poll_handler(
+ int events, int fd, std::function fun, std::function err_cb) {
+ m_poll_handles.emplace_back(std::make_unique(get(), fd, fun, err_cb));
m_poll_handles.back()->start(events);
}
-void eventloop::fs_event_handler(const string& path, std::function fun) {
- m_fs_event_handles.emplace_back(std::make_unique(get(), fun));
+void eventloop::fs_event_handler(
+ const string& path, std::function fun, std::function err_cb) {
+ m_fs_event_handles.emplace_back(std::make_unique(get(), fun, err_cb));
m_fs_event_handles.back()->start(path);
}
diff --git a/src/components/ipc.cpp b/src/components/ipc.cpp
index d89f305a..bc821249 100644
--- a/src/components/ipc.cpp
+++ b/src/components/ipc.cpp
@@ -13,6 +13,13 @@
POLYBAR_NS
+/**
+ * Message types
+ */
+static constexpr const char* ipc_command_prefix{"cmd:"};
+static constexpr const char* ipc_hook_prefix{"hook:"};
+static constexpr const char* ipc_action_prefix{"action:"};
+
/**
* Create instance
*/