fix(rpc): abort in-flight curl on disconnect/shutdown to avoid UI freezes

stop()-ing a worker that is mid curl_easy_perform joined on the UI thread, so a
slow/hung transfer froze the UI until the request timeout. Add RPCClient::
requestAbort() (a thread-safe atomic read by a curl progress callback that aborts
the transfer), and call it before stopping the workers on disconnect
(onDisconnected) and shutdown (beginShutdown + the synchronous fallback). The
flag is cleared on each connect() so a fresh connection never starts aborted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 14:43:34 -05:00
parent 070a516f4e
commit 142a6826af
4 changed files with 48 additions and 2 deletions

View File

@@ -2693,9 +2693,12 @@ void App::beginShutdown()
shutdown_start_time_ = std::chrono::steady_clock::now();
async_tasks_.cancelAll();
// Signal the RPC worker to stop accepting new tasks (non-blocking).
// Signal the RPC worker to stop accepting new tasks (non-blocking), and abort any call
// already in flight so the later join() doesn't wait out a request timeout.
// The actual thread join + rpc disconnect happen in shutdown() after
// the render loop exits, so the UI stays responsive.
if (rpc_) rpc_->requestAbort();
if (fast_rpc_) fast_rpc_->requestAbort();
if (worker_) {
worker_->requestStop();
}
@@ -3308,6 +3311,8 @@ void App::shutdown()
DEBUG_LOGF("Synchronous shutdown fallback...\n");
async_tasks_.cancelAll();
async_tasks_.joinAll();
if (rpc_) rpc_->requestAbort(); // unblock any in-flight curl before joining
if (fast_rpc_) fast_rpc_->requestAbort();
if (worker_) {
worker_->stop();
}