diff --git a/src/ui/windows/mining_benchmark.cpp b/src/ui/windows/mining_benchmark.cpp index 618a697..6bf6bbf 100644 --- a/src/ui/windows/mining_benchmark.cpp +++ b/src/ui/windows/mining_benchmark.cpp @@ -88,6 +88,14 @@ bool ThreadBenchmark::active() const return phase != Phase::Idle && phase != Phase::Done; } +ThreadBenchmarkCancel PlanThreadBenchmarkCancel(const ThreadBenchmark& benchmark) +{ + ThreadBenchmarkCancel plan; + plan.restartThreads = benchmark.prev_threads; + plan.restartMiner = benchmark.was_pool_running && benchmark.prev_threads > 0; + return plan; +} + ThreadBenchmarkUpdate AdvanceThreadBenchmark(ThreadBenchmark& benchmark, float deltaSeconds, double poolHashrate10s) diff --git a/src/ui/windows/mining_benchmark.h b/src/ui/windows/mining_benchmark.h index b28ba31..9ec3a19 100644 --- a/src/ui/windows/mining_benchmark.h +++ b/src/ui/windows/mining_benchmark.h @@ -59,6 +59,15 @@ struct ThreadBenchmarkUpdate { bool inconclusive = false; // finished with no nonzero hashrate sample — caller should warn }; +// What a user-initiated cancel of an active benchmark must do with the miner. Always drop the candidate-thread +// miner; restart only if the user was mining BEFORE the benchmark (snapshot, not live state - the sweep +// transiently stops the miner, so a live check would drop the restore, L-04/L-11). +struct ThreadBenchmarkCancel { + bool restartMiner = false; + int restartThreads = 0; +}; +ThreadBenchmarkCancel PlanThreadBenchmarkCancel(const ThreadBenchmark& benchmark); + ThreadBenchmarkUpdate AdvanceThreadBenchmark(ThreadBenchmark& benchmark, float deltaSeconds, double poolHashrate10s); diff --git a/src/ui/windows/mining_mode_toggle.cpp b/src/ui/windows/mining_mode_toggle.cpp index 8b73e10..059be0e 100644 --- a/src/ui/windows/mining_mode_toggle.cpp +++ b/src/ui/windows/mining_mode_toggle.cpp @@ -117,7 +117,7 @@ void RenderMiningModeToggle(App* app, const WalletState& state, const MiningInfo s_pool_mode = false; app->settings()->setPoolMode(false); app->settings()->save(); - CancelMiningBenchmark(app); // don't leave a pool benchmark running after switching to solo (L-11) + CancelMiningBenchmark(app, false); // don't leave a pool benchmark running after switching to solo (L-11) app->stopPoolMining(); } if (soloHov) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); diff --git a/src/ui/windows/mining_tab.cpp b/src/ui/windows/mining_tab.cpp index c28ed63..3b0855f 100644 --- a/src/ui/windows/mining_tab.cpp +++ b/src/ui/windows/mining_tab.cpp @@ -55,17 +55,16 @@ bool IsMiningBenchmarkActive() { return s_benchmark.active(); } -void CancelMiningBenchmark(App* app) { +void CancelMiningBenchmark(App* app, bool restoreMiner) { if (!s_benchmark.active()) return; - const int restoreThreads = s_benchmark.prev_threads; + const ThreadBenchmarkCancel plan = PlanThreadBenchmarkCancel(s_benchmark); // read BEFORE reset() zeroes both fields s_benchmark.reset(); - // Restore the miner to its pre-benchmark thread count. A benchmark runs in pool mode, so restore - // regardless of the instantaneous running state — the sweep may be mid inter-candidate stop, where an - // isPoolMinerRunning() check would be transiently false and silently drop the restart. (L-04, L-11) - if (app && restoreThreads > 0) { - app->stopPoolMining(); - app->startPoolMining(restoreThreads); - } + if (!app) return; + // Always drop the candidate-thread miner. Restore only if the user was mining before the benchmark, using the + // was_pool_running SNAPSHOT (not the live state: the sweep may be mid inter-candidate stop). (L-04, L-11) + app->stopPoolMining(); + if (restoreMiner && plan.restartMiner) + app->startPoolMining(plan.restartThreads); } // Miner-update version check (one shot per session): fetches the latest DRG-XMRig release tag in diff --git a/src/ui/windows/mining_tab.h b/src/ui/windows/mining_tab.h index 0515925..4a8fc43 100644 --- a/src/ui/windows/mining_tab.h +++ b/src/ui/windows/mining_tab.h @@ -22,11 +22,11 @@ void RenderMiningTab(App* app); bool IsMiningBenchmarkActive(); /** - * @brief Cancel a running thread benchmark and restore the miner to its pre-benchmark thread count. + * @brief Cancel a running thread benchmark and restore the miner only if it was running before the benchmark. * Safe to call when no benchmark is active (no-op). Used when leaving the Mining tab or switching to * solo mode so the miner isn't left stuck at a benchmark step. (L-04, L-11) */ -void CancelMiningBenchmark(App* app); +void CancelMiningBenchmark(App* app, bool restoreMiner = true); } // namespace ui } // namespace dragonx