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 */