Make BuildSummaryStatsModule compatible with Skymeld.

This is a no-op for non Skymeld builds.

PiperOrigin-RevId: 470237073
Change-Id: Ib1eb8951de85c106eb3d3180368ff02ee307304a
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
index 355e3c7..0a6a75b 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
@@ -35,11 +35,13 @@
 import com.google.devtools.build.lib.profiler.ProfilerTask;
 import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.skyframe.ExecutionFinishedEvent;
+import com.google.devtools.build.lib.skyframe.TopLevelStatusEvents.TopLevelTargetPendingExecutionEvent;
 import com.google.devtools.build.lib.vfs.Path;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Blaze module for the build summary message that reports various stats to the user.
@@ -60,6 +62,7 @@
   private long executionEndMillis;
   private SpawnStats spawnStats;
   private Path profilePath;
+  private AtomicBoolean executionStarted;
 
   @Override
   public void beforeCommand(CommandEnvironment env) {
@@ -69,6 +72,7 @@
     commandStartMillis = env.getCommandStartTime();
     this.spawnStats = new SpawnStats();
     eventBus.register(this);
+    executionStarted = new AtomicBoolean(false);
   }
 
   @Override
@@ -77,6 +81,7 @@
     this.eventBus = null;
     this.reporter = null;
     this.spawnStats = null;
+    executionStarted.set(false);
   }
 
   @Override
@@ -87,6 +92,23 @@
 
   @Subscribe
   public void executionPhaseStarting(ExecutionStartingEvent event) {
+    markExecutionPhaseStarted();
+  }
+
+  /**
+   * Skymeld-specific marking of the start of execution. Multiple instances of this event might be
+   * fired during the build, but we make sure to only mark the start of the execution phase when the
+   * first one is received.
+   */
+  @Subscribe
+  public void executionPhaseStarting(
+      @SuppressWarnings("unused") TopLevelTargetPendingExecutionEvent event) {
+    if (executionStarted.compareAndSet(/*expectedValue=*/ false, /*newValue=*/ true)) {
+      markExecutionPhaseStarted();
+    }
+  }
+
+  private void markExecutionPhaseStarted() {
     // TODO(ulfjack): Make sure to use the same clock as for commandStartMillis.
     executionStartMillis = BlazeClock.instance().currentTimeMillis();
     if (enabled) {