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).
This commit is contained in:
parent
2551ea0205
commit
91759a4c96
@ -116,7 +116,7 @@ class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, signals::eve
|
||||
* This handle is used to notify the eventloop of changes which are not otherwise covered by other handles.
|
||||
* E.g. click actions.
|
||||
*/
|
||||
std::unique_ptr<AsyncHandle> m_notifier{nullptr};
|
||||
AsyncHandle_t m_notifier{nullptr};
|
||||
|
||||
/**
|
||||
* Notification data for the controller.
|
||||
|
@ -148,6 +148,14 @@ struct AsyncHandle : public UVHandle<uv_async_t> {
|
||||
}
|
||||
};
|
||||
|
||||
using SignalHandle_t = std::unique_ptr<SignalHandle>;
|
||||
using PollHandle_t = std::unique_ptr<PollHandle>;
|
||||
using FSEventHandle_t = std::unique_ptr<FSEventHandle>;
|
||||
using PipeHandle_t = std::unique_ptr<PipeHandle>;
|
||||
using TimerHandle_t = std::unique_ptr<TimerHandle>;
|
||||
// shared_ptr because we need a reference outside to call send
|
||||
using AsyncHandle_t = std::shared_ptr<AsyncHandle>;
|
||||
|
||||
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<void(int)> fun) {
|
||||
auto handle = std::make_unique<SignalHandle>(get(), fun);
|
||||
handle->start(signum);
|
||||
m_sig_handles.push_back(std::move(handle));
|
||||
m_sig_handles.emplace_back(std::make_unique<SignalHandle>(get(), fun));
|
||||
m_sig_handles.back()->start(signum);
|
||||
}
|
||||
|
||||
void poll_handler(int events, int fd, std::function<void(int, int)> fun) {
|
||||
auto handle = std::make_unique<PollHandle>(get(), fd, fun);
|
||||
handle->start(events);
|
||||
m_poll_handles.push_back(std::move(handle));
|
||||
m_poll_handles.emplace_back(std::make_unique<PollHandle>(get(), fd, fun));
|
||||
m_poll_handles.back()->start(events);
|
||||
}
|
||||
|
||||
void fs_event_handler(const string& path, std::function<void(const char*, int, int)> fun) {
|
||||
auto handle = std::make_unique<FSEventHandle>(get(), fun);
|
||||
handle->start(path);
|
||||
m_fs_event_handles.push_back(std::move(handle));
|
||||
m_fs_event_handles.emplace_back(std::make_unique<FSEventHandle>(get(), fun));
|
||||
m_fs_event_handles.back()->start(path);
|
||||
}
|
||||
|
||||
void pipe_handle(int fd, std::function<void(const string)> fun) {
|
||||
m_pipe_handles.emplace_back(std::make_unique<PipeHandle>(get(), fun));
|
||||
m_pipe_handles.back()->start(fd);
|
||||
}
|
||||
|
||||
void timer_handle(uint64_t timeout, uint64_t repeat, std::function<void(void)> fun) {
|
||||
m_timer_handles.emplace_back(std::make_unique<TimerHandle>(get(), fun));
|
||||
// Trigger a single screenshot after 3 seconds
|
||||
m_timer_handles.back()->start(timeout, repeat);
|
||||
}
|
||||
|
||||
AsyncHandle_t async_handle(std::function<void(void)> fun) {
|
||||
m_async_handles.emplace_back(std::make_shared<AsyncHandle>(get(), fun));
|
||||
return m_async_handles.back();
|
||||
}
|
||||
|
||||
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)...);
|
||||
uv_loop_t* get() const {
|
||||
return m_loop.get();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<uv_loop_t> m_loop{nullptr};
|
||||
|
||||
vector<std::unique_ptr<SignalHandle>> m_sig_handles;
|
||||
vector<std::unique_ptr<PollHandle>> m_poll_handles;
|
||||
vector<std::unique_ptr<FSEventHandle>> m_fs_event_handles;
|
||||
vector<SignalHandle_t> m_sig_handles;
|
||||
vector<PollHandle_t> m_poll_handles;
|
||||
vector<FSEventHandle_t> m_fs_event_handles;
|
||||
vector<PipeHandle_t> m_pipe_handles;
|
||||
vector<TimerHandle_t> m_timer_handles;
|
||||
vector<AsyncHandle_t> m_async_handles;
|
||||
};
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -252,12 +252,8 @@ void controller::read_events(bool confwatch) {
|
||||
m_bar->start();
|
||||
}
|
||||
|
||||
auto ipc_handle = std::unique_ptr<PipeHandle>(nullptr);
|
||||
auto screenshot_timer_handle = std::unique_ptr<TimerHandle>(nullptr);
|
||||
|
||||
try {
|
||||
eloop = std::make_unique<eventloop>();
|
||||
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<PipeHandle>(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<AsyncHandle>(loop, [this]() { notifier_handler(); });
|
||||
|
||||
if (!m_snapshot_dst.empty()) {
|
||||
screenshot_timer_handle = std::make_unique<TimerHandle>(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);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user