diff options
author | vaxerski <[email protected]> | 2022-04-21 22:00:03 +0200 |
---|---|---|
committer | vaxerski <[email protected]> | 2022-04-21 22:00:03 +0200 |
commit | 883d389bc283ac6b29b303a94f063e5575f8416f (patch) | |
tree | e4e454db877af47c649d3747b667099327dde95d | |
parent | 304b93a4f609054bb453f89eb38894809a888b38 (diff) | |
download | Hyprland-883d389bc283ac6b29b303a94f063e5575f8416f.tar.gz Hyprland-883d389bc283ac6b29b303a94f063e5575f8416f.zip |
Make hyprctl thread safe
-rw-r--r-- | src/debug/HyprCtl.cpp | 68 | ||||
-rw-r--r-- | src/debug/HyprCtl.hpp | 5 | ||||
-rw-r--r-- | src/events/Monitors.cpp | 3 |
3 files changed, 63 insertions, 13 deletions
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 2c45c663..160eaff6 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -111,6 +111,60 @@ std::string dispatchKeyword(std::string in) { return retval; } +void HyprCtl::tickHyprCtl() { + if (!requestMade) + return; + + std::string reply = ""; + + try { + if (request == "monitors") + reply = monitorsRequest(); + else if (request == "workspaces") + reply = workspacesRequest(); + else if (request == "clients") + reply = clientsRequest(); + else if (request == "activewindow") + reply = activeWindowRequest(); + else if (request == "layers") + reply = layersRequest(); + else if (request.find("dispatch") == 0) + reply = dispatchRequest(request); + else if (request.find("keyword") == 0) + reply = dispatchKeyword(request); + } catch (std::exception& e) { + Debug::log(ERR, "Error in request: %s", e.what()); + reply = "Err: " + std::string(e.what()); + } + + request = reply; + + requestMade = false; + requestReady = true; +} + +std::string getRequestFromThread(std::string rq) { + while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) { + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } + + HyprCtl::request = rq; + HyprCtl::requestMade = true; + + while (!HyprCtl::requestReady) { + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } + + HyprCtl::requestReady = false; + HyprCtl::requestMade = false; + + std::string toReturn = HyprCtl::request; + + HyprCtl::request = ""; + + return toReturn; +} + void HyprCtl::startHyprCtlSocket() { std::thread([&]() { uint16_t connectPort = 9187; @@ -164,19 +218,7 @@ void HyprCtl::startHyprCtlSocket() { std::string request(readBuffer); - std::string reply = ""; - try { - if (request == "monitors") reply = monitorsRequest(); - else if (request == "workspaces") reply = workspacesRequest(); - else if (request == "clients") reply = clientsRequest(); - else if (request == "activewindow") reply = activeWindowRequest(); - else if (request == "layers") reply = layersRequest(); - else if (request.find("dispatch") == 0) reply = dispatchRequest(request); - else if (request.find("keyword") == 0) reply = dispatchKeyword(request); - } catch (std::exception& e) { - Debug::log(ERR, "Error in request: %s", e.what()); - reply = "Err: " + std::string(e.what()); - } + std::string reply = getRequestFromThread(request); write(ACCEPTEDCONNECTION, reply.c_str(), reply.length()); diff --git a/src/debug/HyprCtl.hpp b/src/debug/HyprCtl.hpp index 1efe468f..3da4aa07 100644 --- a/src/debug/HyprCtl.hpp +++ b/src/debug/HyprCtl.hpp @@ -8,5 +8,10 @@ namespace HyprCtl { void startHyprCtlSocket(); void tickHyprCtl(); + // very simple thread-safe request method + inline bool requestMade = false; + inline bool requestReady = false; + inline std::string request = ""; + inline std::ifstream requestStream; };
\ No newline at end of file diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index 840602bd..3f1d38e1 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -3,6 +3,7 @@ #include "../managers/InputManager.hpp" #include "../render/Renderer.hpp" #include "Events.hpp" +#include "../debug/HyprCtl.hpp" // --------------------------------------------------------- // // __ __ ____ _ _ _____ _______ ____ _____ _____ // @@ -133,6 +134,8 @@ void Events::listener_monitorFrame(void* owner, void* data) { g_pAnimationManager->tick(); g_pCompositor->cleanupWindows(); + HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit + g_pConfigManager->dispatchExecOnce(); // We exec-once when at least one monitor starts refreshing, meaning stuff has init'd if (g_pConfigManager->m_bWantsMonitorReload) |