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(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<ipc> m_ipc;
unique_ptr<inotify_watch> m_confwatch;
eventloop eloop;
std::unique_ptr<eventloop> eloop;
/**
* \brief State flag

View File

@ -6,6 +6,30 @@
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 {
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<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:
std::unique_ptr<uv_loop_t> m_loop{nullptr};
vector<std::unique_ptr<SignalHandle>> m_sig_handles;
};
POLYBAR_NS_END

View File

@ -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();

View File

@ -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<bool>(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<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_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) {
@ -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<eventloop>();
auto loop = eloop->get();
auto conn_handle = std::make_unique<uv_poll_t>();
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<unique_ptr<uv_signal_t>> handles;
for (auto s : {SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGALRM}) {
auto signal_handle = std::make_unique<uv_signal_t>();
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<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);
}
eloop.run();
eloop->run();
eloop.reset();
}
/**

View File

@ -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();
}
}

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_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); */
}
/**

View File

@ -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) {

View File

@ -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");
}