From 91759a4c9623a25f78dda17b392b9deec841685f Mon Sep 17 00:00:00 2001 From: patrick96 Date: Sun, 12 Sep 2021 16:25:23 +0200 Subject: [PATCH] Store all handles inside eventloop This is needed because the handle's lifetime has to be at least the lifetime of the eventloop since the eventloop requires the handle's memory during shutdown (for closing the handles). --- include/components/controller.hpp | 2 +- include/components/eventloop.hpp | 60 +++++++++++++++++++------------ src/components/controller.cpp | 14 +++----- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/include/components/controller.hpp b/include/components/controller.hpp index 323e59b5..58212c73 100644 --- a/include/components/controller.hpp +++ b/include/components/controller.hpp @@ -116,7 +116,7 @@ class controller : public signal_receiver m_notifier{nullptr}; + AsyncHandle_t m_notifier{nullptr}; /** * Notification data for the controller. diff --git a/include/components/eventloop.hpp b/include/components/eventloop.hpp index dabea632..1394c5e7 100644 --- a/include/components/eventloop.hpp +++ b/include/components/eventloop.hpp @@ -148,6 +148,14 @@ struct AsyncHandle : public UVHandle { } }; +using SignalHandle_t = std::unique_ptr; +using PollHandle_t = std::unique_ptr; +using FSEventHandle_t = std::unique_ptr; +using PipeHandle_t = std::unique_ptr; +using TimerHandle_t = std::unique_ptr; +// shared_ptr because we need a reference outside to call send +using AsyncHandle_t = std::shared_ptr; + class eventloop { public: eventloop(); @@ -157,43 +165,51 @@ class eventloop { void stop(); - /** - * TODO make protected - */ - uv_loop_t* get() const { - return m_loop.get(); - } - void signal_handler(int signum, std::function fun) { - auto handle = std::make_unique(get(), fun); - handle->start(signum); - m_sig_handles.push_back(std::move(handle)); + m_sig_handles.emplace_back(std::make_unique(get(), fun)); + m_sig_handles.back()->start(signum); } void poll_handler(int events, int fd, std::function fun) { - auto handle = std::make_unique(get(), fd, fun); - handle->start(events); - m_poll_handles.push_back(std::move(handle)); + m_poll_handles.emplace_back(std::make_unique(get(), fd, fun)); + m_poll_handles.back()->start(events); } void fs_event_handler(const string& path, std::function fun) { - auto handle = std::make_unique(get(), fun); - handle->start(path); - m_fs_event_handles.push_back(std::move(handle)); + m_fs_event_handles.emplace_back(std::make_unique(get(), fun)); + m_fs_event_handles.back()->start(path); + } + + void pipe_handle(int fd, std::function fun) { + m_pipe_handles.emplace_back(std::make_unique(get(), fun)); + m_pipe_handles.back()->start(fd); + } + + void timer_handle(uint64_t timeout, uint64_t repeat, std::function fun) { + m_timer_handles.emplace_back(std::make_unique(get(), fun)); + // Trigger a single screenshot after 3 seconds + m_timer_handles.back()->start(timeout, repeat); + } + + AsyncHandle_t async_handle(std::function fun) { + m_async_handles.emplace_back(std::make_shared(get(), fun)); + return m_async_handles.back(); } protected: - template - static void generic_cb(H* handle, Args&&... args) { - (static_cast(handle->data).*F)(std::forward(args)...); + uv_loop_t* get() const { + return m_loop.get(); } private: std::unique_ptr m_loop{nullptr}; - vector> m_sig_handles; - vector> m_poll_handles; - vector> m_fs_event_handles; + vector m_sig_handles; + vector m_poll_handles; + vector m_fs_event_handles; + vector m_pipe_handles; + vector m_timer_handles; + vector m_async_handles; }; POLYBAR_NS_END diff --git a/src/components/controller.cpp b/src/components/controller.cpp index e4fb8849..a19cbb5e 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -252,12 +252,8 @@ void controller::read_events(bool confwatch) { m_bar->start(); } - auto ipc_handle = std::unique_ptr(nullptr); - auto screenshot_timer_handle = std::unique_ptr(nullptr); - try { eloop = std::make_unique(); - auto loop = eloop->get(); eloop->poll_handler( UV_READABLE, m_connection.get_file_descriptor(), [this](int status, int events) { conn_cb(status, events); }); @@ -272,18 +268,16 @@ void controller::read_events(bool confwatch) { } if (m_ipc) { - ipc_handle = std::make_unique(loop, [this](const string payload) { ipc_cb(payload); }); - ipc_handle->start(m_ipc->get_file_descriptor()); + eloop->pipe_handle(m_ipc->get_file_descriptor(), [this](const string payload) { ipc_cb(payload); }); } - m_notifier = std::make_unique(loop, [this]() { notifier_handler(); }); - if (!m_snapshot_dst.empty()) { - screenshot_timer_handle = std::make_unique(loop, [this]() { screenshot_handler(); }); // Trigger a single screenshot after 3 seconds - screenshot_timer_handle->start(3000, 0); + eloop->timer_handle(3000, 0, [this]() { screenshot_handler(); }); } + m_notifier = eloop->async_handle([this]() { notifier_handler(); }); + m_eloop_ready.store(true); /*