From 65014395b73d850587c1ca4f17f47b417f673e09 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Tue, 6 Oct 2026 11:36:30 +0200 Subject: [PATCH] gui: fix slow agent switching by closing fid on stop When switching agents, the old state/chat streams would block until data arrived (up to 500ms for statewait, indefinitely for chat). Now requestStop() closes the fid from the calling thread, which unblocks the worker's blocking read immediately. This makes agent switching instant instead of waiting for the read timeout. --- kde/gui/lib9pstreamer.cpp | 37 +++++++++++++++++++++++++++++++++---- kde/gui/lib9pstreamer.h | 3 ++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/kde/gui/lib9pstreamer.cpp b/kde/gui/lib9pstreamer.cpp index b8f1b88..a079897 100644 --- a/kde/gui/lib9pstreamer.cpp +++ b/kde/gui/lib9pstreamer.cpp @@ -10,10 +10,24 @@ Lib9pStreamer::Worker::Worker(const QString &path) Lib9pStreamer::Worker::~Worker() { + QMutexLocker lock(&m_fidMutex); if (m_fid >= 0 && m_client) { m_client->closeFid(m_fid); + m_fid = -1; } delete m_client; + m_client = nullptr; +} + +void Lib9pStreamer::Worker::requestStop() +{ + m_stopRequested = true; + // Close the fid to unblock any blocking read + QMutexLocker lock(&m_fidMutex); + if (m_fid >= 0 && m_client) { + m_client->closeFid(m_fid); + m_fid = -1; + } } void Lib9pStreamer::Worker::run() @@ -25,19 +39,34 @@ void Lib9pStreamer::Worker::run() return; } - m_fid = m_client->open(m_path); - if (m_fid < 0) { + int fid = m_client->open(m_path); + if (fid < 0) { emit finished(false, QStringLiteral("Failed to open ") + m_path + ": " + m_client->lastError()); return; } + + { + QMutexLocker lock(&m_fidMutex); + if (m_stopRequested) { + // Stop requested while opening + m_client->closeFid(fid); + emit finished(true, QString()); + return; + } + m_fid = fid; + } // Read loop char buf[8192]; while (!m_stopRequested) { int n = m_client->readFid(m_fid, buf, sizeof(buf)); if (n < 0) { - // Error - emit finished(false, m_client->lastError()); + // Error — could be from requestStop closing the fid + if (m_stopRequested) { + emit finished(true, QString()); + } else { + emit finished(false, m_client->lastError()); + } return; } if (n == 0) { diff --git a/kde/gui/lib9pstreamer.h b/kde/gui/lib9pstreamer.h index ffbcfca..5dc4db0 100644 --- a/kde/gui/lib9pstreamer.h +++ b/kde/gui/lib9pstreamer.h @@ -69,7 +69,7 @@ public: explicit Worker(const QString &path); ~Worker() override; - void requestStop() { m_stopRequested = true; } + void requestStop(); public slots: void run(); @@ -83,6 +83,7 @@ private: volatile bool m_stopRequested = false; Lib9pClient *m_client = nullptr; int m_fid = -1; + QMutex m_fidMutex; // protects m_fid during close }; #endif // LIB9PSTREAMER_H