aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorvaxerski <[email protected]>2022-04-21 22:00:03 +0200
committervaxerski <[email protected]>2022-04-21 22:00:03 +0200
commit883d389bc283ac6b29b303a94f063e5575f8416f (patch)
treee4e454db877af47c649d3747b667099327dde95d
parent304b93a4f609054bb453f89eb38894809a888b38 (diff)
downloadHyprland-883d389bc283ac6b29b303a94f063e5575f8416f.tar.gz
Hyprland-883d389bc283ac6b29b303a94f063e5575f8416f.zip
Make hyprctl thread safe
-rw-r--r--src/debug/HyprCtl.cpp68
-rw-r--r--src/debug/HyprCtl.hpp5
-rw-r--r--src/events/Monitors.cpp3
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)