fix(rpc): keep the worker alive on non-std throws; atomic flags

The RPC worker loop only caught std::exception. A task that threw
anything else - a non-std exception propagating out of a posted job -
escaped the loop and tore down the worker thread, so every later RPC
silently went unanswered.

- The worker loop now also has a catch-all that swallows non-std
  throws and keeps the thread running. Such a job still loses its
  main-thread callback, exactly as the std::exception path already
  did; the only change is that the worker survives.
- RPCClient's connected_ and warming_up_ flags are now atomic. They
  are read from the UI thread while the worker updates them, so the
  plain bools were a data race.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 07:21:07 -05:00
co-authored by Claude Opus 4.8
parent 7e7804e577
commit d9143f0e18
2 changed files with 6 additions and 2 deletions
+2 -2
View File
@@ -301,9 +301,9 @@ private:
std::string host_;
std::string port_;
std::string auth_; // Base64 encoded "user:password"
bool connected_ = false;
std::atomic<bool> connected_{false};
std::atomic<bool> abort_{false}; // set cross-thread to abort an in-flight transfer
bool warming_up_ = false;
std::atomic<bool> warming_up_{false};
std::string warmup_status_;
std::string last_connect_error_;
RpcFailureKind last_connect_kind_ = RpcFailureKind::None;
+4
View File
@@ -142,6 +142,10 @@ void RPCWorker::run()
}
} catch (const std::exception& e) {
DEBUG_LOGF("[RPCWorker] Task threw: %s\n", e.what());
} catch (...) {
// A raw post() job that throws still loses its MainCb (no worse than the
// std::exception path); this only keeps the worker thread alive.
DEBUG_LOGF("[RPCWorker] Task threw unknown exception\n");
}
}
}