Move signal handling to eventloop class

This commit is contained in:
patrick96 2021-03-02 00:00:24 +01:00 committed by Patrick Ziegler
parent a2f50f3b90
commit 3cc17a0e57
8 changed files with 74 additions and 23 deletions

View File

@ -53,6 +53,8 @@ class controller
bool enqueue(event&& evt); bool enqueue(event&& evt);
bool enqueue(string&& input_data); bool enqueue(string&& input_data);
void signal_handler(int signum);
void conn_cb(int status, int events); void conn_cb(int status, int events);
void ipc_cb(string buf); void ipc_cb(string buf);
@ -88,7 +90,7 @@ class controller
unique_ptr<ipc> m_ipc; unique_ptr<ipc> m_ipc;
unique_ptr<inotify_watch> m_confwatch; unique_ptr<inotify_watch> m_confwatch;
eventloop eloop; std::unique_ptr<eventloop> eloop;
/** /**
* \brief State flag * \brief State flag

View File

@ -6,6 +6,30 @@
POLYBAR_NS POLYBAR_NS
template <class H, class... Args>
struct cb_helper {
std::function<void(Args...)> func;
static void callback(H* context, Args... args) {
const auto unpackedThis = static_cast<const cb_helper*>(context->data);
return unpackedThis->func(std::forward<Args>(args)...);
}
};
struct SignalHandle {
SignalHandle(uv_loop_t* loop, std::function<void(int)> fun) {
handle = std::make_unique<uv_signal_t>();
// TODO handle return value
uv_signal_init(loop, handle.get());
cb = cb_helper<uv_signal_t, int>{fun};
handle->data = &cb;
};
std::unique_ptr<uv_signal_t> handle;
cb_helper<uv_signal_t, int> cb;
};
class eventloop { class eventloop {
public: public:
eventloop(); eventloop();
@ -16,14 +40,28 @@ class eventloop {
void stop(); void stop();
/** /**
* TODO remove * TODO make protected
*/ */
uv_loop_t* get() const { uv_loop_t* get() const {
return m_loop.get(); return m_loop.get();
} }
void signal_handler(int signum, std::function<void(int)> fun) {
auto handle = std::make_unique<SignalHandle>(get(), fun);
uv_signal_start(handle->handle.get(), &handle->cb.callback, signum);
m_sig_handles.push_back(std::move(handle));
}
protected:
template <typename H, typename T, typename... Args, void (T::*F)(Args...)>
static void generic_cb(H* handle, Args&&... args) {
(static_cast<T*>(handle->data).*F)(std::forward<Args>(args)...);
}
private: private:
std::unique_ptr<uv_loop_t> m_loop{nullptr}; std::unique_ptr<uv_loop_t> m_loop{nullptr};
vector<std::unique_ptr<SignalHandle>> m_sig_handles;
}; };
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -29,7 +29,7 @@ class file_ptr {
class file_descriptor { class file_descriptor {
public: 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); explicit file_descriptor(int fd, bool autoclose = true);
~file_descriptor(); ~file_descriptor();

View File

@ -134,7 +134,6 @@ bool controller::run(bool writeback, string snapshot_dst) {
read_events(); read_events();
if (m_event_thread.joinable()) { if (m_event_thread.joinable()) {
enqueue(make_quit_evt(static_cast<bool>(g_reload)));
m_event_thread.join(); m_event_thread.join();
} }
@ -179,7 +178,7 @@ void controller::conn_cb(int, int) {
if (m_connection.connection_has_error()) { if (m_connection.connection_has_error()) {
g_terminate = 1; g_terminate = 1;
g_reload = 0; g_reload = 0;
eloop.stop(); eloop->stop();
return; return;
} }
@ -204,10 +203,10 @@ static void conn_cb_wrapper(uv_poll_t* handle, int status, int events) {
static_cast<controller*>(handle->data)->conn_cb(status, events); static_cast<controller*>(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_terminate = 1;
g_reload = (signum == SIGUSR1); g_reload = (signum == SIGUSR1);
static_cast<eventloop*>(handle->loop->data)->stop(); eloop->stop();
} }
static void confwatch_cb_wrapper(uv_fs_event_t* handle, const char* fname, int, int) { 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() { void controller::read_events() {
m_log.info("Entering event loop (thread-id=%lu)", this_thread::get_id()); m_log.info("Entering event loop (thread-id=%lu)", this_thread::get_id());
auto loop = eloop.get(); eloop = std::make_unique<eventloop>();
auto loop = eloop->get();
auto conn_handle = std::make_unique<uv_poll_t>(); auto conn_handle = std::make_unique<uv_poll_t>();
uv_poll_init(loop, conn_handle.get(), m_connection.get_file_descriptor()); 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); uv_poll_start(conn_handle.get(), UV_READABLE, conn_cb_wrapper);
std::vector<unique_ptr<uv_signal_t>> handles;
for (auto s : {SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGALRM}) { for (auto s : {SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGALRM}) {
auto signal_handle = std::make_unique<uv_signal_t>(); eloop->signal_handler(s, [this](int signum) { signal_handler(signum); });
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));
} }
auto conf_handle = std::unique_ptr<uv_fs_event_t>(nullptr); auto conf_handle = std::unique_ptr<uv_fs_event_t>(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); uv_read_start((uv_stream_t*)ipc_handle.get(), ipc_alloc_cb, ipc_read_cb_wrapper);
} }
eloop.run(); eloop->run();
eloop.reset();
} }
/** /**

View File

@ -10,10 +10,30 @@ eventloop::eventloop() {
m_loop->data = this; 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() { eventloop::~eventloop() {
if (m_loop) { if (m_loop) {
close_loop(m_loop.get());
uv_loop_close(m_loop.get()); uv_loop_close(m_loop.get());
// TODO handle return value // TODO handle return value
m_loop.reset();
} }
} }

View File

@ -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_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 * Deconstruct ipc handler
*/ */
ipc::~ipc() { ipc::~ipc() {
m_fd.reset();
if (!m_path.empty()) { if (!m_path.empty()) {
m_log.trace("ipc: Removing file handle"); m_log.trace("ipc: Removing file handle");
unlink(m_path.c_str()); unlink(m_path.c_str());
@ -66,8 +64,6 @@ void ipc::receive_message(string buf) {
} else if (!payload.empty()) { } else if (!payload.empty()) {
m_log.warn("Received unknown ipc message: (payload=%s)", payload); m_log.warn("Received unknown ipc message: (payload=%s)", payload);
} }
/* m_fd = file_util::make_file_descriptor(m_path, O_RDONLY | O_NONBLOCK); */
} }
/** /**

View File

@ -86,6 +86,7 @@ namespace modules {
* Handler for XCB_PROPERTY_NOTIFY events * Handler for XCB_PROPERTY_NOTIFY events
*/ */
void xwindow_module::handle(const evt::property_notify& evt) { 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) { if (evt->atom == _NET_ACTIVE_WINDOW) {
update(true); update(true);
} else if (evt->atom == _NET_CURRENT_DESKTOP) { } else if (evt->atom == _NET_CURRENT_DESKTOP) {

View File

@ -52,7 +52,7 @@ file_ptr::operator int() const {
// }}} // }}}
// implementation of file_descriptor {{{ // 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) { if ((m_fd = open(path.c_str(), flags)) == -1) {
throw system_error("Failed to open file descriptor"); throw system_error("Failed to open file descriptor");
} }