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(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
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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) {
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user