aboutsummaryrefslogtreecommitdiff
path: root/src/nix/progress-bar.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/nix/progress-bar.cc')
-rw-r--r--src/nix/progress-bar.cc50
1 files changed, 35 insertions, 15 deletions
diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc
index fb9955190..252d12c5d 100644
--- a/src/nix/progress-bar.cc
+++ b/src/nix/progress-bar.cc
@@ -3,8 +3,9 @@
#include "sync.hh"
#include "store-api.hh"
-#include <map>
#include <atomic>
+#include <map>
+#include <thread>
namespace nix {
@@ -101,15 +102,28 @@ private:
Sync<State> state_;
+ std::thread updateThread;
+
+ std::condition_variable quitCV, updateCV;
+
public:
ProgressBar()
{
+ updateThread = std::thread([&]() {
+ auto state(state_.lock());
+ while (state->active) {
+ state.wait(updateCV);
+ draw(*state);
+ state.wait_for(quitCV, std::chrono::milliseconds(50));
+ }
+ });
}
~ProgressBar()
{
stop();
+ updateThread.join();
}
void stop()
@@ -121,6 +135,8 @@ public:
writeToStderr("\r\e[K");
if (status != "")
writeToStderr("[" + status + "]\n");
+ updateCV.notify_one();
+ quitCV.notify_one();
}
void log(Verbosity lvl, const FormatOrString & fs) override
@@ -132,7 +148,7 @@ public:
void log(State & state, Verbosity lvl, const std::string & s)
{
writeToStderr("\r\e[K" + s + ANSI_NORMAL "\n");
- update(state);
+ draw(state);
}
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
@@ -167,7 +183,12 @@ public:
if (type == actSubstitute) {
auto name = storePathToName(getS(fields, 0));
- i->s = fmt("fetching " ANSI_BOLD "%s" ANSI_NORMAL " from %s", name, getS(fields, 1));
+ auto sub = getS(fields, 1);
+ i->s = fmt(
+ hasPrefix(sub, "local")
+ ? "copying " ANSI_BOLD "%s" ANSI_NORMAL " from %s"
+ : "fetching " ANSI_BOLD "%s" ANSI_NORMAL " from %s",
+ name, sub);
}
if (type == actQueryPathInfo) {
@@ -180,7 +201,7 @@ public:
|| (type == actCopyPath && hasAncestor(*state, actSubstitute, parent)))
i->visible = false;
- update(*state);
+ update();
}
/* Check whether an activity has an ancestore with the specified
@@ -215,7 +236,7 @@ public:
state->its.erase(i);
}
- update(*state);
+ update();
}
void result(ActivityId act, ResultType type, const std::vector<Field> & fields) override
@@ -225,7 +246,7 @@ public:
if (type == resFileLinked) {
state->filesLinked++;
state->bytesLinked += getI(fields, 0);
- update(*state);
+ update();
}
else if (type == resBuildLogLine) {
@@ -238,25 +259,25 @@ public:
info.lastLine = lastLine;
state->activities.emplace_back(info);
i->second = std::prev(state->activities.end());
- update(*state);
+ update();
}
}
else if (type == resUntrustedPath) {
state->untrustedPaths++;
- update(*state);
+ update();
}
else if (type == resCorruptedPath) {
state->corruptedPaths++;
- update(*state);
+ update();
}
else if (type == resSetPhase) {
auto i = state->its.find(act);
assert(i != state->its.end());
i->second->phase = getS(fields, 0);
- update(*state);
+ update();
}
else if (type == resProgress) {
@@ -267,7 +288,7 @@ public:
actInfo.expected = getI(fields, 1);
actInfo.running = getI(fields, 2);
actInfo.failed = getI(fields, 3);
- update(*state);
+ update();
}
else if (type == resSetExpected) {
@@ -279,17 +300,16 @@ public:
state->activitiesByType[type].expected -= j;
j = getI(fields, 1);
state->activitiesByType[type].expected += j;
- update(*state);
+ update();
}
}
void update()
{
- auto state(state_.lock());
- update(*state);
+ updateCV.notify_one();
}
- void update(State & state)
+ void draw(State & state)
{
if (!state.active) return;