perf(app): run miner shutdown off the UI thread

At quit the UI thread drained and joined the mining-control thread and
then called the miner's blocking stop with a 3 s budget. Both ran on the
UI thread, so the window could stall for up to that long before the
shutdown screen rendered.

- Quit now only signals the mining-control thread (no join) on the UI
  thread. The blocking teardown — join the control thread, then stop the
  miner — moves to a background thread, so xmrig still has a single
  driver but the UI thread never blocks on it.
- On the daemon-stop path that teardown runs first on the shutdown
  thread, so the miner is fully stopped before the daemon stop begins.
  On the disconnect-only quit paths it runs on its own thread, which
  the final shutdown joins before tearing xmrig down, so there is never
  a second concurrent join of the control thread.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 06:26:13 -05:00
co-authored by Claude Opus 4.8
parent 30f5243dd1
commit 8df0fe1734
2 changed files with 35 additions and 10 deletions
+3
View File
@@ -1196,7 +1196,9 @@ private:
std::deque<std::function<void()>> mining_ctl_queue_;
bool mining_ctl_stop_ = false;
void postMiningControl(std::function<void()> job); // enqueue a blocking xmrig op onto the FIFO thread
void signalMiningControlStop(); // signal only (no join): safe on the UI thread
void stopMiningControlThread(); // signal + join the control thread (shutdown)
void finishMinerShutdown(); // join control thread -> xmrig stop(3000); background only
// Builds the pool config on the main thread and posts stop(if running)+start to the control thread.
// retargetOnly: a thread-count change, decided on the control thread (never starts a miner).
void postPoolMinerJob(int threads, bool retargetOnly);
@@ -1262,6 +1264,7 @@ private:
bool address_list_dirty_ = false; // P8: dedup rebuildAddressList
GuardedStatus shutdown_status_; // thread-safe: written by the shutdown thread, read by the UI (M-05)
std::thread shutdown_thread_;
std::thread miner_stop_thread_; // disconnect-only quit paths: miner teardown off the UI thread
// Confirm-before-stopping-daemon-mid-witness-rebuild guard (see beginShutdown / renderDaemonStopConfirm)
bool pending_shutdown_confirm_ = false; // a quit is deferred, waiting to open the confirm modal
bool daemon_stop_confirm_open_ = false; // the confirm modal is currently showing