Unlock rewinding locks on exceptions and add profiler spans (https://github.com/bazelbuild/bazel/pull/30649)

### Description
This guards against interrupts and Errors causing locks to be held indefinitely.

Along the way add more profiler spans.

### Motivation

### Build API Changes

No

### Checklist

- [ ] I have added tests for the new use cases (if any).
- [ ] I have updated the documentation (if applicable).

### Release Notes

RELNOTES: None

Closes #30649.

PiperOrigin-RevId: 966728317
Change-Id: I7d7b23ee366cc956f89840203415fbf8a7940e95
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteRewoundActionSynchronizer.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteRewoundActionSynchronizer.java
index b14263d..960680d 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteRewoundActionSynchronizer.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteRewoundActionSynchronizer.java
@@ -149,7 +149,10 @@
     if (localCoarseLock != null) {
       // This is the first time a rewound action has attempted to prepare for its execution.
       // Switch to using the fine locks under the protection of the coarse write lock.
-      localCoarseLock.writeLock().lockInterruptibly();
+      try (SilentCloseable c =
+          Profiler.instance().profile(ProfilerTask.ACTION_LOCK, "action.prepareFirstRewinding")) {
+        localCoarseLock.writeLock().lockInterruptibly();
+      }
       try {
         // Check again under the lock to avoid a race between multiple rewound actions attempting
         // to prepare for execution at the same time.
@@ -166,6 +169,8 @@
                   // (https://github.com/openjdk/jdk/blob/b349f661ea5f14b258191134714a7e712c90ef3e/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java#L1039),
                   // TODO: Investigate the effect of fair locks on build wall time.
                   .build((ActionLookupData unused) -> new StampedLock().asReadWriteLock());
+          // Must be assigned after fineLocks as lockArtifactsForConsumption relies on a null
+          // coarseLock implying a non-null fineLocks.
           coarseLock = null;
         }
       } finally {
@@ -174,8 +179,18 @@
     }
 
     var writeLock = fineLocks.get(outputKeyFor(action)).writeLock();
-    writeLock.lockInterruptibly();
-    prepareOutputsForRewinding(action);
+    try (SilentCloseable c =
+        Profiler.instance()
+            .profile(ProfilerTask.ACTION_LOCK, "action.awaitRewoundActionConsumers")) {
+      writeLock.lockInterruptibly();
+    }
+    try (SilentCloseable c =
+        Profiler.instance().profile(ProfilerTask.INFO, "action.prepareOutputsForRewinding")) {
+      prepareOutputsForRewinding(action);
+    } catch (Throwable t) {
+      writeLock.unlock();
+      throw t;
+    }
     return writeLock::unlock;
   }
 
@@ -265,7 +280,7 @@
         readLock.lockInterruptibly();
         locksToUnlockBuilder.add(readLock);
       }
-    } catch (InterruptedException e) {
+    } catch (Throwable e) {
       for (var readLock : locksToUnlockBuilder.build()) {
         readLock.unlock();
       }