aboutsummaryrefslogtreecommitdiff
path: root/compatibility
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2016-11-27 16:00:58 -0500
committerChristopher Vogt <oss.nsp@cvogt.org>2017-02-01 23:10:49 -0500
commite56f8afa03035140280bc8d3d878ad225def381e (patch)
treec04ee4dee271ebf84777c0b47a639fde475fa9bf /compatibility
parent00d9485f5597fdecc58461bd81df635fafbe494f (diff)
downloadcbt-e56f8afa03035140280bc8d3d878ad225def381e.tar.gz
cbt-e56f8afa03035140280bc8d3d878ad225def381e.tar.bz2
cbt-e56f8afa03035140280bc8d3d878ad225def381e.zip
replace flawed concurrent hashmap cache with consistent replacement
The concurrent hashmap approach to classloader caching was flawed. Assume you have two concurrently running builds A and B and projects P2 and P3 depending on project P1. And assume a time sequence where A compiles P1, then compiles P2, then P1’s sources change, then B compiles P1, then A compiles P3. At the end P2 and P3 will have different versions of P1 as their parent classloaders. This is inconsistent. The easiest way to work around this is making sure only one thread is changing the classloader cache during it’s entire run. This would mean either no concurrency or what we have done here, which is letting threads work on a copy of the cache and replace the original cache in the end using an atomic operation. This means the thread that finishes last wins, but for caching that’s fine. Worst case some things aren’t cached in a concurrent execution. This change also means that we don’t need concurrent hashmaps for the classloader cache anymore since no two theads will access the same hashmap. We still need a concurrent hashmap for the class caches inside of the classloaders as multiple threads can access the same classloaders.
Diffstat (limited to 'compatibility')
-rw-r--r--compatibility/Context.java6
1 files changed, 3 insertions, 3 deletions
diff --git a/compatibility/Context.java b/compatibility/Context.java
index 5a0f9c6..a7af740 100644
--- a/compatibility/Context.java
+++ b/compatibility/Context.java
@@ -1,6 +1,6 @@
package cbt;
import java.io.*;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.*;
// TODO: try to reduce the number of members
public abstract class Context{
@@ -11,8 +11,8 @@ public abstract class Context{
public abstract Long startCompat();
public abstract Boolean cbtHasChangedCompat();
public abstract String scalaVersionOrNull(); // needed to propagate scalaVersion to dependendee builds
- public abstract ConcurrentHashMap<Object,Object> persistentCache();
- public abstract ConcurrentHashMap<Object,Object> transientCache();
+ public abstract Map<Object,Object> persistentCache();
+ public abstract Map<Object,Object> transientCache();
public abstract File cache();
public abstract File cbtHome();
public abstract File cbtRootHome(); // REMOVE