aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java')
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java63
1 files changed, 42 insertions, 21 deletions
diff --git a/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java b/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
index 543ccf4c42..096fc2d49b 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
@@ -22,7 +22,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.concurrent.AbstractQueueVisitor;
import com.google.devtools.build.lib.concurrent.ErrorClassifier;
-import com.google.devtools.build.lib.concurrent.ErrorHandler;
import com.google.devtools.build.lib.concurrent.ExecutorParams;
import com.google.devtools.build.lib.concurrent.ForkJoinQuiescingExecutor;
import com.google.devtools.build.lib.concurrent.QuiescingExecutor;
@@ -31,7 +30,6 @@ import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.skyframe.QueryableGraph.Reason;
import com.google.devtools.build.skyframe.ThinNodeEntry.MarkedDirtyResult;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
@@ -41,7 +39,6 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
-
import javax.annotation.Nullable;
/**
@@ -113,8 +110,7 @@ public abstract class InvalidatingNodeVisitor<TGraph extends QueryableGraph> {
/*failFastOnException=*/ true,
"skyframe-invalidator",
executorFactory,
- errorClassifier,
- ErrorHandler.NullHandler.INSTANCE);
+ errorClassifier);
this.graph = Preconditions.checkNotNull(graph);
this.invalidationReceiver = invalidationReceiver;
this.dirtyKeyTracker = Preconditions.checkNotNull(dirtyKeyTracker);
@@ -126,9 +122,8 @@ public abstract class InvalidatingNodeVisitor<TGraph extends QueryableGraph> {
@Nullable EvaluationProgressReceiver invalidationReceiver,
InvalidationState state,
DirtyKeyTracker dirtyKeyTracker,
- ForkJoinPool forkJoinPool,
- ErrorHandler errorHandler) {
- this.executor = new ForkJoinQuiescingExecutor(forkJoinPool, errorClassifier, errorHandler);
+ ForkJoinPool forkJoinPool) {
+ this.executor = new ForkJoinQuiescingExecutor(forkJoinPool, errorClassifier);
this.graph = Preconditions.checkNotNull(graph);
this.invalidationReceiver = invalidationReceiver;
this.dirtyKeyTracker = Preconditions.checkNotNull(dirtyKeyTracker);
@@ -270,7 +265,7 @@ public abstract class InvalidatingNodeVisitor<TGraph extends QueryableGraph> {
for (SkyKey key : unvisitedKeys) {
pendingVisitations.add(Pair.of(key, InvalidationType.DELETED));
}
- final Map<SkyKey, NodeEntry> entries =
+ final Map<SkyKey, ? extends NodeEntry> entries =
graph.getBatch(null, Reason.INVALIDATION, unvisitedKeys);
for (final SkyKey key : unvisitedKeys) {
executor.execute(
@@ -303,13 +298,23 @@ public abstract class InvalidatingNodeVisitor<TGraph extends QueryableGraph> {
entry.isDone()
? ImmutableSet.<SkyKey>of()
: entry.getTemporaryDirectDeps().toSet();
- Iterable<SkyKey> directDeps =
- entry.isDone()
- ? entry.getDirectDeps()
- : entry.getAllDirectDepsForIncompleteNode();
- Map<SkyKey, NodeEntry> depMap =
+ Iterable<SkyKey> directDeps;
+ try {
+ directDeps =
+ entry.isDone()
+ ? entry.getDirectDeps()
+ : entry.getAllDirectDepsForIncompleteNode();
+ } catch (InterruptedException e) {
+ throw new IllegalStateException(
+ "Deletion cannot happen on a graph that may have blocking operations: "
+ + key
+ + ", "
+ + entry,
+ e);
+ }
+ Map<SkyKey, ? extends NodeEntry> depMap =
graph.getBatch(key, Reason.INVALIDATION, directDeps);
- for (Map.Entry<SkyKey, NodeEntry> directDepEntry : depMap.entrySet()) {
+ for (Map.Entry<SkyKey, ? extends NodeEntry> directDepEntry : depMap.entrySet()) {
NodeEntry dep = directDepEntry.getValue();
if (dep != null) {
if (dep.isDone() || !signalingDeps.contains(directDepEntry.getKey())) {
@@ -373,9 +378,8 @@ public abstract class InvalidatingNodeVisitor<TGraph extends QueryableGraph> {
InvalidationState state,
DirtyKeyTracker dirtyKeyTracker,
ForkJoinPool forkJoinPool,
- boolean supportInterruptions,
- ErrorHandler errorHandler) {
- super(graph, invalidationReceiver, state, dirtyKeyTracker, forkJoinPool, errorHandler);
+ boolean supportInterruptions) {
+ super(graph, invalidationReceiver, state, dirtyKeyTracker, forkJoinPool);
this.supportInterruptions = supportInterruptions;
}
@@ -435,8 +439,16 @@ public abstract class InvalidatingNodeVisitor<TGraph extends QueryableGraph> {
pendingVisitations.add(Pair.of(key, invalidationType));
}
}
- final Map<SkyKey, ? extends ThinNodeEntry> entries =
- graph.getBatch(null, Reason.INVALIDATION, keysToGet);
+ final Map<SkyKey, ? extends ThinNodeEntry> entries;
+ try {
+ entries = graph.getBatch(null, Reason.INVALIDATION, keysToGet);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ // This can only happen if the main thread has been interrupted, and so the
+ // AbstractQueueVisitor is shutting down. We haven't yet removed the pending visitations, so
+ // we can resume next time.
+ return;
+ }
if (enqueueingKeyForExistenceCheck != null && entries.size() != keysToGet.size()) {
Set<SkyKey> missingKeys = Sets.difference(ImmutableSet.copyOf(keysToGet), entries.keySet());
throw new IllegalStateException(
@@ -471,7 +483,16 @@ public abstract class InvalidatingNodeVisitor<TGraph extends QueryableGraph> {
// method.
// Any exception thrown should be unrecoverable.
// This entry remains in the graph in this dirty state until it is re-evaluated.
- MarkedDirtyResult markedDirtyResult = entry.markDirty(isChanged);
+ MarkedDirtyResult markedDirtyResult = null;
+ try {
+ markedDirtyResult = entry.markDirty(isChanged);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ // This can only happen if the main thread has been interrupted, and so the
+ // AbstractQueueVisitor is shutting down. We haven't yet removed the pending
+ // visitation, so we can resume next time.
+ return;
+ }
if (markedDirtyResult == null) {
// Another thread has already dirtied this node. Don't do anything in this thread.
if (supportInterruptions) {