fix(sway/ipc): reconnect on disconnect instead of breaking + CPU-spinning

When sway's event-subscription send buffer overflows during an event
flood, sway closes the client connection. The sway IPC event worker
(SleeperThread running handleEvent -> recv) then threw on every
iteration and the SleeperThread immediately re-invoked it, leaving the
sway modules broken while busy-looping on a dead socket and pegging a
CPU.

Mirror the niri backend's reconnect loop: on a read/EOF/parse error from
the event socket, close the old connection, back off for a couple of
seconds (so we don't busy-spin), re-open the socket and replay the same
subscriptions, then resume. A running_ flag set at the start of teardown
makes the worker bail out cleanly instead of reconnecting to a socket
that is being closed on purpose. The IPC message protocol and event
parsing are unchanged.

Fixes #3166.
This commit is contained in:
Alex
2026-07-04 13:43:01 +02:00
parent 8ff8ceeca2
commit b0b46ec039
2 changed files with 57 additions and 5 deletions
+10
View File
@@ -2,10 +2,12 @@
#include <sigc++/sigc++.h>
#include <atomic>
#include <cstdint>
#include <functional>
#include <mutex>
#include <string>
#include <vector>
#include "ipc.hpp"
#include "util/SafeSignal.hpp"
@@ -43,6 +45,14 @@ class Ipc {
struct ipc_response send(int fd, uint32_t type, const std::string& payload = "");
struct ipc_response recv(int fd);
// Re-establish the event socket and re-subscribe after sway drops us, backing
// off between attempts so we don't busy-loop while sway is unavailable.
void reconnectEvent();
std::string socketPath_;
std::vector<std::string> subscribed_events_;
std::atomic<bool> running_{true};
util::ScopedFd fd_;
util::ScopedFd fd_event_;
std::mutex mutex_;