mirror of https://github.com/sbt/sbt.git
Fix global lock implementation for ComponentManager
This commit is contained in:
parent
a33bb71f50
commit
94b8fb5a19
|
|
@ -1,7 +1,7 @@
|
|||
package xsbt
|
||||
|
||||
import java.io.{File,FileOutputStream}
|
||||
import ComponentManager.lock
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
/** A component manager provides access to the pieces of xsbt that are distributed as components.
|
||||
* There are two types of components. The first type is compiled subproject jars with their dependencies.
|
||||
|
|
@ -12,7 +12,7 @@ import ComponentManager.lock
|
|||
* This is used for compiled source jars so that the compilation need not be repeated for other projects on the same
|
||||
* machine.
|
||||
*/
|
||||
class ComponentManager(provider: xsbti.ComponentProvider, val log: IvyLogger) extends NotNull
|
||||
class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, val log: IvyLogger) extends NotNull
|
||||
{
|
||||
/** Get all of the files for component 'id', throwing an exception if no files exist for the component. */
|
||||
def files(id: String)(ifMissing: IfMissing): Iterable[File] =
|
||||
|
|
@ -36,11 +36,12 @@ class ComponentManager(provider: xsbti.ComponentProvider, val log: IvyLogger) ex
|
|||
if(d.cache) cache(id)
|
||||
getOrElse(notFound)
|
||||
}
|
||||
|
||||
|
||||
lockLocalCache { getOrElse(fromGlobal) }
|
||||
}
|
||||
private def lockLocalCache[T](action: => T): T = lock("local cache", provider.lockFile, log) ( action )
|
||||
private def lockGlobalCache[T](action: => T): T = lock("global cache", IvyCache.lockFile, log)( action )
|
||||
private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)( action )
|
||||
private def lockGlobalCache[T](action: => T): T = lock(IvyCache.lockFile)( action )
|
||||
private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action })
|
||||
/** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */
|
||||
def file(id: String)(ifMissing: IfMissing): File =
|
||||
files(id)(ifMissing).toList match {
|
||||
|
|
@ -68,20 +69,4 @@ object IfMissing
|
|||
{
|
||||
object Fail extends IfMissing
|
||||
final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define }
|
||||
}
|
||||
object ComponentManager
|
||||
{
|
||||
def lock[T](label: String, file: File, log: IvyLogger)(action: => T): T =
|
||||
{
|
||||
synchronized {
|
||||
val channel = new FileOutputStream(file).getChannel
|
||||
try {
|
||||
val freeLock = channel.tryLock
|
||||
val lock = if(freeLock eq null) { log.info("Waiting for " + label + " to be available..."); channel.lock } else freeLock
|
||||
try { action }
|
||||
finally { lock.release() }
|
||||
}
|
||||
finally { channel.close() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ private object NotInCache
|
|||
/** Provides methods for working at the level of a single jar file with the default Ivy cache.*/
|
||||
object IvyCache
|
||||
{
|
||||
def lockFile = new File(System.getProperty("temp.dir"), "sbt.cache.lock")
|
||||
def lockFile = new File(System.getProperty("java.io.tmpdir"), "sbt.cache.lock")
|
||||
/** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/
|
||||
def cacheJar(moduleID: ModuleID, file: File, log: IvyLogger)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -77,5 +77,5 @@ object ComponentManagerTest extends Specification
|
|||
private def writeRandomContent(file: File) = FileUtilities.write(file, randomString)
|
||||
private def randomString = "asdf"
|
||||
private def withManager[T](f: ComponentManager => T): T =
|
||||
TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(new xsbt.boot.ComponentProvider(temp), logger)) } )
|
||||
TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp), logger)) } )
|
||||
}
|
||||
Loading…
Reference in New Issue