Move signal handling to eventloop class
This commit is contained in:
parent
a2f50f3b90
commit
3cc17a0e57
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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); */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user