about summary refs log tree commit diff
path: root/src/nix/progress-bar.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-06-25T19·57+0200
committerEelco Dolstra <edolstra@gmail.com>2019-06-25T19·59+0200
commit324a5dc92f8e50e6b637c5e67dea48c80be10837 (patch)
tree88f14b074294d6f2af26e02e1a33bb6f40442dd7 /src/nix/progress-bar.cc
parent88571219d97f2bdfdbafcff25ef6ee424b0b008f (diff)
ProgressBar: Fix updating
'updateCV.notify_one()' does nothing if the update thread is not
waiting for updateCV (in particular this happens when it is sleeping
on quitCV). So also set a variable to ensure that the update isn't
lost.
Diffstat (limited to 'src/nix/progress-bar.cc')
-rw-r--r--src/nix/progress-bar.cc26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc
index e7104540816b..b1c1d87de1a2 100644
--- a/src/nix/progress-bar.cc
+++ b/src/nix/progress-bar.cc
@@ -62,6 +62,7 @@ private:
         uint64_t corruptedPaths = 0, untrustedPaths = 0;
 
         bool active = true;
+        bool haveUpdate = true;
     };
 
     Sync<State> state_;
@@ -83,7 +84,8 @@ public:
         updateThread = std::thread([&]() {
             auto state(state_.lock());
             while (state->active) {
-                state.wait(updateCV);
+                if (!state->haveUpdate)
+                    state.wait(updateCV);
                 draw(*state);
                 state.wait_for(quitCV, std::chrono::milliseconds(50));
             }
@@ -178,7 +180,7 @@ public:
             || (type == actCopyPath && hasAncestor(*state, actSubstitute, parent)))
             i->visible = false;
 
-        update();
+        update(*state);
     }
 
     /* Check whether an activity has an ancestore with the specified
@@ -213,7 +215,7 @@ public:
             state->its.erase(i);
         }
 
-        update();
+        update(*state);
     }
 
     void result(ActivityId act, ResultType type, const std::vector<Field> & fields) override
@@ -223,7 +225,7 @@ public:
         if (type == resFileLinked) {
             state->filesLinked++;
             state->bytesLinked += getI(fields, 0);
-            update();
+            update(*state);
         }
 
         else if (type == resBuildLogLine) {
@@ -239,26 +241,26 @@ public:
                     info.lastLine = lastLine;
                     state->activities.emplace_back(info);
                     i->second = std::prev(state->activities.end());
-                    update();
+                    update(*state);
                 }
             }
         }
 
         else if (type == resUntrustedPath) {
             state->untrustedPaths++;
-            update();
+            update(*state);
         }
 
         else if (type == resCorruptedPath) {
             state->corruptedPaths++;
-            update();
+            update(*state);
         }
 
         else if (type == resSetPhase) {
             auto i = state->its.find(act);
             assert(i != state->its.end());
             i->second->phase = getS(fields, 0);
-            update();
+            update(*state);
         }
 
         else if (type == resProgress) {
@@ -269,7 +271,7 @@ public:
             actInfo.expected = getI(fields, 1);
             actInfo.running = getI(fields, 2);
             actInfo.failed = getI(fields, 3);
-            update();
+            update(*state);
         }
 
         else if (type == resSetExpected) {
@@ -281,17 +283,19 @@ public:
             state->activitiesByType[type].expected -= j;
             j = getI(fields, 1);
             state->activitiesByType[type].expected += j;
-            update();
+            update(*state);
         }
     }
 
-    void update()
+    void update(State & state)
     {
+        state.haveUpdate = true;
         updateCV.notify_one();
     }
 
     void draw(State & state)
     {
+        state.haveUpdate = false;
         if (!state.active) return;
 
         std::string line;