Merge pull request #578 from alebastr/ipc-use-after-free

fix(sway): resolve destruction dependency between Ipc and SleeperThread
pull/579/head
Alex 2020-02-06 17:36:11 +00:00 committed by GitHub
commit e1215a6d17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 37 additions and 54 deletions

View File

@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include "ipc.hpp" #include "ipc.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules::sway { namespace waybar::modules::sway {
@ -28,6 +29,7 @@ class Ipc {
void sendCmd(uint32_t type, const std::string &payload = ""); void sendCmd(uint32_t type, const std::string &payload = "");
void subscribe(const std::string &payload); void subscribe(const std::string &payload);
void handleEvent(); void handleEvent();
void setWorker(std::function<void()> &&func);
protected: protected:
static inline const std::string ipc_magic_ = "i3-ipc"; static inline const std::string ipc_magic_ = "i3-ipc";
@ -38,9 +40,10 @@ class Ipc {
struct ipc_response send(int fd, uint32_t type, const std::string &payload = ""); struct ipc_response send(int fd, uint32_t type, const std::string &payload = "");
struct ipc_response recv(int fd); struct ipc_response recv(int fd);
int fd_; int fd_;
int fd_event_; int fd_event_;
std::mutex mutex_; std::mutex mutex_;
util::SleeperThread thread_;
}; };
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -6,7 +6,6 @@
#include "client.hpp" #include "client.hpp"
#include "modules/sway/ipc/client.hpp" #include "modules/sway/ipc/client.hpp"
#include "util/json.hpp" #include "util/json.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules::sway { namespace waybar::modules::sway {
@ -18,14 +17,11 @@ class Mode : public ALabel, public sigc::trackable {
private: private:
void onEvent(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&);
void worker();
std::string mode_; std::string mode_;
util::JsonParser parser_; util::JsonParser parser_;
std::mutex mutex_; std::mutex mutex_;
Ipc ipc_;
util::SleeperThread thread_;
Ipc ipc_;
}; };
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -7,7 +7,6 @@
#include "client.hpp" #include "client.hpp"
#include "modules/sway/ipc/client.hpp" #include "modules/sway/ipc/client.hpp"
#include "util/json.hpp" #include "util/json.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules::sway { namespace waybar::modules::sway {
@ -20,7 +19,6 @@ class Window : public ALabel, public sigc::trackable {
private: private:
void onEvent(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&);
void onCmd(const struct Ipc::ipc_response&); void onCmd(const struct Ipc::ipc_response&);
void worker();
std::tuple<std::size_t, int, std::string, std::string> getFocusedNode(const Json::Value& nodes, std::tuple<std::size_t, int, std::string, std::string> getFocusedNode(const Json::Value& nodes,
std::string& output); std::string& output);
void getTree(); void getTree();
@ -33,9 +31,7 @@ class Window : public ALabel, public sigc::trackable {
std::size_t app_nb_; std::size_t app_nb_;
util::JsonParser parser_; util::JsonParser parser_;
std::mutex mutex_; std::mutex mutex_;
Ipc ipc_;
util::SleeperThread thread_;
Ipc ipc_;
}; };
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -8,7 +8,6 @@
#include "client.hpp" #include "client.hpp"
#include "modules/sway/ipc/client.hpp" #include "modules/sway/ipc/client.hpp"
#include "util/json.hpp" #include "util/json.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules::sway { namespace waybar::modules::sway {
@ -21,7 +20,6 @@ class Workspaces : public AModule, public sigc::trackable {
private: private:
void onCmd(const struct Ipc::ipc_response&); void onCmd(const struct Ipc::ipc_response&);
void onEvent(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&);
void worker();
bool filterButtons(); bool filterButtons();
Gtk::Button& addButton(const Json::Value&); Gtk::Button& addButton(const Json::Value&);
void onButtonReady(const Json::Value&, Gtk::Button&); void onButtonReady(const Json::Value&, Gtk::Button&);
@ -38,9 +36,7 @@ class Workspaces : public AModule, public sigc::trackable {
util::JsonParser parser_; util::JsonParser parser_;
std::unordered_map<std::string, Gtk::Button> buttons_; std::unordered_map<std::string, Gtk::Button> buttons_;
std::mutex mutex_; std::mutex mutex_;
Ipc ipc_;
util::SleeperThread thread_;
Ipc ipc_;
}; };
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -10,19 +10,23 @@ Ipc::Ipc() {
} }
Ipc::~Ipc() { Ipc::~Ipc() {
// To fail the IPC header thread_.stop();
write(fd_, "close-sway-ipc", 14);
write(fd_event_, "close-sway-ipc", 14);
if (fd_ > 0) { if (fd_ > 0) {
// To fail the IPC header
write(fd_, "close-sway-ipc", 14);
close(fd_); close(fd_);
fd_ = -1; fd_ = -1;
} }
if (fd_event_ > 0) { if (fd_event_ > 0) {
write(fd_event_, "close-sway-ipc", 14);
close(fd_event_); close(fd_event_);
fd_event_ = -1; fd_event_ = -1;
} }
} }
void Ipc::setWorker(std::function<void()>&& func) { thread_ = func; }
const std::string Ipc::getSocketPath() const { const std::string Ipc::getSocketPath() const {
const char* env = getenv("SWAYSOCK"); const char* env = getenv("SWAYSOCK");
if (env != nullptr) { if (env != nullptr) {

View File

@ -8,7 +8,13 @@ Mode::Mode(const std::string& id, const Json::Value& config)
ipc_.subscribe(R"(["mode"])"); ipc_.subscribe(R"(["mode"])");
ipc_.signal_event.connect(sigc::mem_fun(*this, &Mode::onEvent)); ipc_.signal_event.connect(sigc::mem_fun(*this, &Mode::onEvent));
// Launch worker // Launch worker
worker(); ipc_.setWorker([this] {
try {
ipc_.handleEvent();
} catch (const std::exception& e) {
spdlog::error("Mode: {}", e.what());
}
});
dp.emit(); dp.emit();
} }
@ -31,16 +37,6 @@ void Mode::onEvent(const struct Ipc::ipc_response& res) {
} }
} }
void Mode::worker() {
thread_ = [this] {
try {
ipc_.handleEvent();
} catch (const std::exception& e) {
spdlog::error("Mode: {}", e.what());
}
};
}
auto Mode::update() -> void { auto Mode::update() -> void {
if (mode_.empty()) { if (mode_.empty()) {
event_box_.hide(); event_box_.hide();

View File

@ -11,7 +11,13 @@ Window::Window(const std::string& id, const Bar& bar, const Json::Value& config)
// Get Initial focused window // Get Initial focused window
getTree(); getTree();
// Launch worker // Launch worker
worker(); ipc_.setWorker([this] {
try {
ipc_.handleEvent();
} catch (const std::exception& e) {
spdlog::error("Window: {}", e.what());
}
});
} }
void Window::onEvent(const struct Ipc::ipc_response& res) { getTree(); } void Window::onEvent(const struct Ipc::ipc_response& res) { getTree(); }
@ -28,16 +34,6 @@ void Window::onCmd(const struct Ipc::ipc_response& res) {
} }
} }
void Window::worker() {
thread_ = [this] {
try {
ipc_.handleEvent();
} catch (const std::exception& e) {
spdlog::error("Window: {}", e.what());
}
};
}
auto Window::update() -> void { auto Window::update() -> void {
if (!old_app_id_.empty()) { if (!old_app_id_.empty()) {
bar_.window.get_style_context()->remove_class(old_app_id_); bar_.window.get_style_context()->remove_class(old_app_id_);

View File

@ -22,7 +22,13 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value
window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll)); window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
} }
// Launch worker // Launch worker
worker(); ipc_.setWorker([this] {
try {
ipc_.handleEvent();
} catch (const std::exception &e) {
spdlog::error("Workspaces: {}", e.what());
}
});
} }
void Workspaces::onEvent(const struct Ipc::ipc_response &res) { void Workspaces::onEvent(const struct Ipc::ipc_response &res) {
@ -102,16 +108,6 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) {
} }
} }
void Workspaces::worker() {
thread_ = [this] {
try {
ipc_.handleEvent();
} catch (const std::exception &e) {
spdlog::error("Workspaces: {}", e.what());
}
};
}
bool Workspaces::filterButtons() { bool Workspaces::filterButtons() {
bool needReorder = false; bool needReorder = false;
for (auto it = buttons_.begin(); it != buttons_.end();) { for (auto it = buttons_.begin(); it != buttons_.end();) {