diff --git a/src/main/java/com/google/devtools/build/lib/runtime/UiStateTracker.java b/src/main/java/com/google/devtools/build/lib/runtime/UiStateTracker.java index c709eb36316840..eef7ea5c64ae7c 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/UiStateTracker.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/UiStateTracker.java @@ -62,12 +62,14 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.PriorityQueue; import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.Nullable; +import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.ThreadSafe; /** Tracks state for the UI. */ @@ -228,6 +230,7 @@ private ProgressState(String id, long nanoStartTime) { } } + @GuardedBy("this") private final LinkedHashMap runningProgresses = new LinkedHashMap<>(); /** Starts tracking the state of an action. */ @@ -333,6 +336,13 @@ synchronized void onProgressEvent(ActionProgressEvent event, long nanoChangeTime state.latestEvent = event; } + synchronized Optional firstProgress() { + if (runningProgresses.isEmpty()) { + return Optional.empty(); + } + return Optional.of(runningProgresses.entrySet().iterator().next().getValue()); + } + /** Generates a human-readable description of this action's state. */ synchronized String describe() { if (runningStrategiesBitmap != 0) { @@ -705,12 +715,12 @@ private String describeTestGroup( } private String describeActionProgress(ActionState action, int desiredWidth) { - if (action.runningProgresses.isEmpty()) { + Optional stateOpt = action.firstProgress(); + if (!stateOpt.isPresent()) { return ""; } - ActionState.ProgressState state = - action.runningProgresses.entrySet().iterator().next().getValue(); + ActionState.ProgressState state = stateOpt.get(); ActionProgressEvent event = state.latestEvent; String message = event.progress(); if (message.isEmpty()) {