diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 49865aa90..7269bdba5 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -622,7 +622,7 @@ ProcessLineResult NixRepl::processLine(std::string line) // TODO: this only shows a progress bar for explicitly initiated builds, // not eval-time fetching or builds performed for IFD. // But we can't just show it everywhere, since that would erase partial output from evaluation. - startProgressBar(); + logger->resume(); Finally stopLogger([&]() { stopProgressBar(); }); diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc index d83b09cd4..6b5fcdef8 100644 --- a/src/libmain/progress-bar.cc +++ b/src/libmain/progress-bar.cc @@ -82,6 +82,22 @@ private: bool haveUpdate = true; }; + void createUpdateThread() + { + this->updateThread = std::thread([&]() { + auto state(state_.lock()); + auto nextWakeup = A_LONG_TIME; + while (state->active) { + if (!state->haveUpdate) { + state.wait_for(updateCV, nextWakeup); + } + + nextWakeup = draw(*state); + state.wait_for(quitCV, std::chrono::milliseconds(50)); + } + }); + } + Sync state_; std::thread updateThread; @@ -97,16 +113,7 @@ public: : isTTY(isTTY) { state_.lock()->active = isTTY; - updateThread = std::thread([&]() { - auto state(state_.lock()); - auto nextWakeup = A_LONG_TIME; - while (state->active) { - if (!state->haveUpdate) - state.wait_for(updateCV, nextWakeup); - nextWakeup = draw(*state); - state.wait_for(quitCV, std::chrono::milliseconds(50)); - } - }); + this->createUpdateThread(); } ~ProgressBar() @@ -133,10 +140,21 @@ public: writeToStderr("\r\e[K"); } - void resume() override { - state_.lock()->paused = false; - writeToStderr("\r\e[K"); - state_.lock()->haveUpdate = true; + void resume() override + { + { + auto lockedState(this->state_.lock()); + lockedState->paused = false; + writeToStderr("\r\e[K"); + lockedState->haveUpdate = true; + } + + // We must lock individually here, as createUpdateThread() also locks. + if (!state_.lock()->active) { + state_.lock()->active = true; + this->createUpdateThread(); + } + updateCV.notify_one(); }