mirror of
https://github.com/sbt/sbt.git
synced 2026-10-06 10:03:56 +02:00
Synchronize at a higher level on the Scala provider cache.
Construction of Scala providers was already properly synchronized jvm and machine-wide. The cache on top of construction was not. This could cause the same Scala version to be loaded in multiple class loaders.
This commit is contained in:
+1
-1
@@ -9,7 +9,7 @@ import java.util.HashMap
|
||||
final class Cache[K,X,V](create: (K,X) => V)
|
||||
{
|
||||
private[this] val delegate = new HashMap[K,Reference[V]]
|
||||
def apply(k: K, x: X): V = getFromReference(k, x, delegate.get(k))
|
||||
def apply(k: K, x: X): V = synchronized { getFromReference(k, x, delegate.get(k)) }
|
||||
private[this] def getFromReference(k: K, x: X, existingRef: Reference[V]) = if(existingRef eq null) newEntry(k, x) else get(k, x, existingRef.get)
|
||||
private[this] def get(k: K, x: X, existing: V) = if(existing == null) newEntry(k, x) else existing
|
||||
private[this] def newEntry(k: K, x: X): V =
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import sbt._
|
||||
import Keys._
|
||||
|
||||
object Build extends Build {
|
||||
|
||||
lazy val checkLoader = TaskKey[Unit]("check-loaders")
|
||||
|
||||
def checkTask = subs.map(sub => scalaInstance in LocalProject(sub.id)).join.map { sis =>
|
||||
assert(sis.sliding(2).forall{ case Seq(x,y) => x.loader == y.loader }, "Not all ScalaInstances had the same class loader.")
|
||||
}
|
||||
|
||||
override def projects = root +: subs
|
||||
lazy val root = Project("root", file(".")).settings( checkLoader <<= checkTask )
|
||||
lazy val subs = ( for(i <- 1 to 20) yield newProject(i) ).toSeq
|
||||
|
||||
def newProject(i: Int): Project = Project("x" + i.toString, file(i.toString)).settings(
|
||||
scalaVersion := "2.10.2"
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# verify that the class loader for Scala used for each project is the same
|
||||
> check-loaders
|
||||
Reference in New Issue
Block a user