diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc index 4db49f02c..2d4d901db 100644 --- a/src/libmain/progress-bar.cc +++ b/src/libmain/progress-bar.cc @@ -73,8 +73,13 @@ private: uint64_t corruptedPaths = 0, untrustedPaths = 0; bool active = true; - bool paused = false; + size_t suspensions = 0; bool haveUpdate = true; + + bool isPaused() const + { + return suspensions > 0; + } }; /** Helps avoid unnecessary redraws, see `redraw()` */ @@ -130,18 +135,30 @@ public: void pause() override { auto state (state_.lock()); - state->paused = true; + state->suspensions++; + if (state->suspensions > 1) { + // already paused + return; + } + if (state->active) writeToStderr("\r\e[K"); } void resume() override { auto state (state_.lock()); - state->paused = false; - if (state->active) - writeToStderr("\r\e[K"); - state->haveUpdate = true; - updateCV.notify_one(); + if (state->suspensions == 0) { + log(lvlError, "nix::ProgressBar: resume() called without a matching preceding pause(). This is a bug."); + return; + } else { + state->suspensions--; + } + if (state->suspensions == 0) { + if (state->active) + writeToStderr("\r\e[K"); + state->haveUpdate = true; + updateCV.notify_one(); + } } bool isVerbose() override @@ -383,7 +400,7 @@ public: auto nextWakeup = std::chrono::milliseconds::max(); state.haveUpdate = false; - if (state.paused || !state.active) return nextWakeup; + if (state.isPaused() || !state.active) return nextWakeup; std::string line;