ExperimentalEventHandler: narrow scope of synchronized blocks

...to in particular never own a lock while waiting for the
update thread to finish. This avoids a deadlock when the update
thread tries to enter the synchronized part of doRefresh while
the thread trying to stop the update thread holds the lock.

Also renable experimental_ui_test now that the race condition leading
to the deadlock is fixed. The absence of flakiness has been verified
by running the test locally 100 times. Fixes #1560.

--
Change-Id: I5d85b347e6cb7a1da8d5a724d6f9cd7461e33e5b
Reviewed-on: https://bazel-review.googlesource.com/#/c/4225
MOS_MIGRATED_REVID=129079398
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java b/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java
index 16609ca..1ba9523 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java
@@ -309,31 +309,37 @@
   }
 
   @Subscribe
-  public synchronized void buildComplete(BuildCompleteEvent event) {
+  public void buildComplete(BuildCompleteEvent event) {
     // The final progress bar will flow into the scroll-back buffer, to if treat
     // it as an event and add a time stamp, if events are supposed to have a time stmap.
-    if (showTimestamp) {
-      stateTracker.buildComplete(event, TIMESTAMP_FORMAT.print(clock.currentTimeMillis()));
-    } else {
-      stateTracker.buildComplete(event);
+    synchronized (this) {
+      if (showTimestamp) {
+        stateTracker.buildComplete(event, TIMESTAMP_FORMAT.print(clock.currentTimeMillis()));
+      } else {
+        stateTracker.buildComplete(event);
+      }
+      ignoreRefreshLimitOnce();
+      refresh();
+      buildComplete = true;
     }
-    ignoreRefreshLimitOnce();
-    refresh();
-    buildComplete = true;
     stopUpdateThread();
     flushStdOutStdErrBuffers();
   }
 
   @Subscribe
-  public synchronized void noBuild(NoBuildEvent event) {
-    buildComplete = true;
+  public void noBuild(NoBuildEvent event) {
+    synchronized (this) {
+      buildComplete = true;
+    }
     stopUpdateThread();
     flushStdOutStdErrBuffers();
   }
 
   @Subscribe
-  public synchronized void afterCommand(AfterCommandEvent event) {
-    buildComplete = true;
+  public void afterCommand(AfterCommandEvent event) {
+    synchronized (this) {
+      buildComplete = true;
+    }
     stopUpdateThread();
   }
 
diff --git a/src/test/shell/integration/BUILD b/src/test/shell/integration/BUILD
index 9224c46..35958d4 100644
--- a/src/test/shell/integration/BUILD
+++ b/src/test/shell/integration/BUILD
@@ -36,7 +36,6 @@
     srcs = ["experimental_ui_test.sh"],
     data = [":test-deps"],
     shard_count = 6,
-    tags = ["manual"],
 )
 
 sh_test(