aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe
diff options
context:
space:
mode:
authorGravatar twerth <twerth@google.com>2018-03-07 02:46:37 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-03-07 02:47:50 -0800
commite5626a53e108fe9de2af84fb2cf0c38eb72cdc4f (patch)
tree4172ed792208bc96eb4e75be282dcfd656d5a022 /src/main/java/com/google/devtools/build/lib/skyframe
parent54027090564fee03bc7f710dfe37e61218fef519 (diff)
Don't use computeIfAbsent in action graph dumping.
computeIfAbsent may throw (on best effort basis) a ConcurrentModificationException if you change the underlying Map in the computeIfAbsent call, for example when you call computeIfAbsent recursively in the mappingFunction. NestedSets are an inherent recursive structure, so we need to call computeIfAbsent recursively in the action graph dump. Since computeIfAbsent doesn't throw the exception all the time, it's hard to come up with a reliable test case. RELNOTES: None PiperOrigin-RevId: 188151283
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/BaseCache.java13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/BaseCache.java b/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/BaseCache.java
index f2eb7b4cd7..f2b3d8697a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/BaseCache.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/BaseCache.java
@@ -39,12 +39,17 @@ abstract class BaseCache<K, P> {
String dataToId(K data) {
K key = transformToKey(data);
- return cache.computeIfAbsent(key, k -> {
- String id = generateNextId();
+ String id = cache.get(key);
+ if (id == null) {
+ // Note that this cannot be replaced by computeIfAbsent since createProto is a recursive
+ // operation for the case of nested sets which will call dataToId on the same object and thus
+ // computeIfAbsent again.
+ id = generateNextId();
+ cache.put(key, id);
P proto = createProto(data, id);
addToActionGraphBuilder(proto);
- return id;
- });
+ }
+ return id;
}
abstract P createProto(K key, String id);