diff options
author | Janak Ramakrishnan <janakr@google.com> | 2015-04-13 16:07:16 +0000 |
---|---|---|
committer | Philipp Wollermann <philwo@google.com> | 2015-04-14 14:30:47 +0000 |
commit | b8eed8aa039f8ad06c09c00caec8999f589ccd27 (patch) | |
tree | 4d44c84aca3f48ad749f2527f458df4bbcc95adc /src/main/java | |
parent | f5c6097be39e38822b48a685547fbefca47b6f14 (diff) |
Fix race when two shared actions don't know about each other until after they have started executing in SkyframeActionExecutor.
We were updating the action cache for both actions in this case, but one of the actions' metadata handler was not updated during execution, and thus it had no metadata for outputs.
--
MOS_MIGRATED_REVID=90993813
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java index 917d7834d0..0f75188190 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java @@ -358,6 +358,12 @@ public final class SkyframeActionExecutor { return buildActionMap.containsKey(action.getPrimaryOutput()); } + private boolean actionReallyExecuted(Action action) { + Pair<Action, ?> cachedRun = Preconditions.checkNotNull( + buildActionMap.get(action.getPrimaryOutput()), action); + return action == cachedRun.first; + } + /** * Executes the provided action on the current thread. Returns the ActionExecutionValue with the * result, either computed here or already computed on another thread. @@ -486,6 +492,12 @@ public final class SkyframeActionExecutor { } void afterExecution(Action action, ActionMetadataHandler metadataHandler, Token token) { + if (!actionReallyExecuted(action)) { + // If an action shared with this one executed, then we need not update the action cache, since + // the other action will do it. Moreover, this action is not aware of metadata acquired + // during execution, so its metadata handler is likely unusable anyway. + return; + } try { actionCacheChecker.afterExecution(action, token, metadataHandler); } catch (IOException e) { |