Better error handling
This commit is contained in:
parent
53ce1ae414
commit
9d9fe8bffb
@ -53,6 +53,8 @@ class controller
|
||||
bool enqueue(event&& evt);
|
||||
bool enqueue(string&& input_data);
|
||||
|
||||
void stop(bool reload);
|
||||
|
||||
void signal_handler(int signum);
|
||||
|
||||
void conn_cb(int status, int events);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "components/logger.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
@ -12,11 +13,13 @@ POLYBAR_NS
|
||||
* Runs any libuv function with an integer error code return value and throws an
|
||||
* exception on error.
|
||||
*/
|
||||
#define UV(fun, ...) \
|
||||
int res = fun(__VA_ARGS__); \
|
||||
if (res < 0) { \
|
||||
throw std::runtime_error("libuv error for '" #fun "': "s + uv_strerror(res)); \
|
||||
}
|
||||
#define UV(fun, ...) \
|
||||
do { \
|
||||
int res = fun(__VA_ARGS__); \
|
||||
if (res < 0) { \
|
||||
throw std::runtime_error("libuv error for '" #fun "': "s + uv_strerror(res)); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
template <class H, class... Args>
|
||||
struct cb_helper {
|
||||
@ -51,7 +54,7 @@ struct SignalHandle : public UVHandle<uv_signal_t, int> {
|
||||
};
|
||||
|
||||
struct PollHandle : public UVHandle<uv_poll_t, int, int> {
|
||||
// TODO wrap callback and handle negative status
|
||||
// TODO wrap callback and handle status
|
||||
PollHandle(uv_loop_t* loop, int fd, std::function<void(int, int)> fun) : UVHandle(fun) {
|
||||
UV(uv_poll_init, loop, handle.get(), fd);
|
||||
}
|
||||
|
@ -27,6 +27,13 @@ namespace {
|
||||
return !(id == static_cast<int>(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create QUIT event
|
||||
*/
|
||||
inline event make_none_evt() {
|
||||
return event{static_cast<int>(event_type::NONE)};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create QUIT event
|
||||
*/
|
||||
|
@ -134,6 +134,7 @@ bool controller::run(bool writeback, string snapshot_dst) {
|
||||
read_events();
|
||||
|
||||
if (m_event_thread.joinable()) {
|
||||
m_log.info("Joining event thread");
|
||||
m_event_thread.join();
|
||||
}
|
||||
|
||||
@ -153,9 +154,6 @@ bool controller::enqueue(event&& evt) {
|
||||
m_log.warn("Failed to enqueue event");
|
||||
return false;
|
||||
}
|
||||
// if (write(g_eventpipe[PIPE_WRITE], " ", 1) == -1) {
|
||||
// m_log.err("Failed to write to eventpipe (reason: %s)", strerror(errno));
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -172,17 +170,28 @@ bool controller::enqueue(string&& input_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void controller::conn_cb(int, int) {
|
||||
// TODO handle negative status
|
||||
if (m_connection.connection_has_error()) {
|
||||
g_terminate = 1;
|
||||
g_reload = 0;
|
||||
eloop->stop();
|
||||
void controller::stop(bool reload) {
|
||||
g_terminate = 1;
|
||||
g_reload = 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;
|
||||
}
|
||||
|
||||
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));
|
||||
stop(false);
|
||||
return;
|
||||
}
|
||||
|
||||
shared_ptr<xcb_generic_event_t> evt{};
|
||||
while ((evt = shared_ptr<xcb_generic_event_t>(xcb_poll_for_event(m_connection), free)) != nullptr) {
|
||||
if ((evt = shared_ptr<xcb_generic_event_t>(xcb_poll_for_event(m_connection), free)) != nullptr) {
|
||||
try {
|
||||
m_connection.dispatch_event(evt);
|
||||
} catch (xpp::connection_error& err) {
|
||||
@ -190,6 +199,12 @@ void controller::conn_cb(int, int) {
|
||||
} catch (const exception& err) {
|
||||
m_log.err("Error in X event loop: %s", err.what());
|
||||
}
|
||||
} else {
|
||||
if ((xcb_error = m_connection.connection_has_error()) > 0) {
|
||||
m_log.err("X connection error, terminating... (what: %s)", m_connection.error_str(xcb_error));
|
||||
stop(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,19 +215,15 @@ void controller::ipc_cb(string buf) {
|
||||
|
||||
void controller::signal_handler(int signum) {
|
||||
m_log.notice("Received signal SIG%s", sigabbrev_np(signum));
|
||||
g_terminate = 1;
|
||||
g_reload = (signum == SIGUSR1);
|
||||
eloop->stop();
|
||||
stop(signum == SIGUSR1);
|
||||
}
|
||||
|
||||
void controller::confwatch_handler(const char*, int, int) {
|
||||
g_terminate = 1;
|
||||
g_reload = 1;
|
||||
eloop->stop();
|
||||
void controller::confwatch_handler(const char* filename, int, int) {
|
||||
m_log.notice("Watched config file changed %s", filename);
|
||||
stop(true);
|
||||
}
|
||||
|
||||
static void ipc_alloc_cb(uv_handle_t*, size_t, uv_buf_t* buf) {
|
||||
// TODO handle alloc error
|
||||
buf->base = new char[BUFSIZ];
|
||||
buf->len = BUFSIZ;
|
||||
}
|
||||
@ -271,10 +282,14 @@ void controller::read_events() {
|
||||
eloop->run();
|
||||
} catch (const exception& err) {
|
||||
m_log.err("Fatal Error in eventloop: %s", err.what());
|
||||
g_terminate = 1;
|
||||
eloop->stop();
|
||||
stop(false);
|
||||
}
|
||||
|
||||
// Notify event queue so that it stops
|
||||
enqueue(make_none_evt());
|
||||
|
||||
m_log.info("Eventloop finished");
|
||||
|
||||
eloop.reset();
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ int main(int argc, char** argv) {
|
||||
// against pid if one was defined
|
||||
for (auto&& channel : pipes) {
|
||||
try {
|
||||
file_descriptor fd(channel, O_WRONLY | O_NONBLOCK);
|
||||
file_descriptor fd(channel, O_WRONLY | O_NONBLOCK, true);
|
||||
string payload{ipc_type + ':' + ipc_payload};
|
||||
if (write(fd, payload.c_str(), payload.size()) != -1) {
|
||||
display("Successfully wrote \"" + payload + "\" to \"" + channel + "\"");
|
||||
|
Loading…
Reference in New Issue
Block a user