Refactor the legacy globbing thread pool to make use of more modern concurrency abstractions.
Care is taken to maintain the invariant that the glob result returns after all of the work is done, even if there was an exception that cuts the task short. Interruption is an exception to this: In this case, the GlobCache later cancels the task and ensures it is done.
--
MOS_MIGRATED_REVID=97000506
diff --git a/src/main/java/com/google/devtools/build/lib/packages/GlobCache.java b/src/main/java/com/google/devtools/build/lib/packages/GlobCache.java
index 95166a9..de9bfdf 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/GlobCache.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/GlobCache.java
@@ -35,6 +35,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
@@ -322,7 +323,7 @@
for (Future<List<Path>> task : tasks) {
try {
fromFuture(task);
- } catch (IOException | InterruptedException e) {
+ } catch (CancellationException | IOException | InterruptedException e) {
// Ignore: If this was still going on in the background, some other
// failure already occurred.
}
@@ -332,10 +333,12 @@
private static void cancelBackgroundTasks(Collection<Future<List<Path>>> tasks) {
for (Future<List<Path>> task : tasks) {
task.cancel(true);
+ }
+ for (Future<List<Path>> task : tasks) {
try {
task.get();
- } catch (ExecutionException | InterruptedException e) {
+ } catch (CancellationException | ExecutionException | InterruptedException e) {
// We don't care. Point is, the task does not bother us anymore.
}
}