synchronized functions in zip filesystem and moved try-catch in factory method, hopefully prevents issues in mcpc+; allowing any type of value as os env var for more flexibility where needed

This commit is contained in:
Florian Nücke 2014-02-17 20:04:39 +01:00
parent 5a162c8058
commit 1845ba0e17
3 changed files with 69 additions and 56 deletions

View File

@ -17,7 +17,7 @@ class ZipFileInputStreamFileSystem(private val archive: ArchiveDirectory) extend
def spaceUsed = spaceUsed_ def spaceUsed = spaceUsed_
private lazy val spaceUsed_ = { private lazy val spaceUsed_ = ZipFileInputStreamFileSystem.synchronized {
def recurse(d: ArchiveDirectory): Long = d.children.foldLeft(0L)((acc, c) => acc + (c match { def recurse(d: ArchiveDirectory): Long = d.children.foldLeft(0L)((acc, c) => acc + (c match {
case directory: ArchiveDirectory => recurse(directory) case directory: ArchiveDirectory => recurse(directory)
case file: ArchiveFile => file.size case file: ArchiveFile => file.size
@ -27,28 +27,40 @@ class ZipFileInputStreamFileSystem(private val archive: ArchiveDirectory) extend
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def exists(path: String) = entry(path).isDefined override def exists(path: String) = ZipFileInputStreamFileSystem.synchronized {
entry(path).isDefined
override def size(path: String) = entry(path) match {
case Some(file) if !file.isDirectory => file.size
case _ => 0L
} }
override def isDirectory(path: String) = entry(path).exists(_.isDirectory) override def size(path: String) = ZipFileInputStreamFileSystem.synchronized {
entry(path) match {
def lastModified(path: String) = entry(path) match { case Some(file) if !file.isDirectory => file.size
case Some(file) => file.lastModified case _ => 0L
case _ => 0L }
} }
override def list(path: String) = entry(path) match { override def isDirectory(path: String) = ZipFileInputStreamFileSystem.synchronized {
case Some(entry) if entry.isDirectory => entry.list() entry(path).exists(_.isDirectory)
case _ => null }
def lastModified(path: String) = ZipFileInputStreamFileSystem.synchronized {
entry(path) match {
case Some(file) => file.lastModified
case _ => 0L
}
}
override def list(path: String) = ZipFileInputStreamFileSystem.synchronized {
entry(path) match {
case Some(entry) if entry.isDirectory => entry.list()
case _ => null
}
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override protected def openInputStream(path: String) = entry(path).map(_.openStream()) override protected def openInputStream(path: String) = ZipFileInputStreamFileSystem.synchronized {
entry(path).map(_.openStream())
}
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@ -65,51 +77,53 @@ object ZipFileInputStreamFileSystem {
asInstanceOf[CacheBuilder[String, ArchiveDirectory]]. asInstanceOf[CacheBuilder[String, ArchiveDirectory]].
build[String, ArchiveDirectory]() build[String, ArchiveDirectory]()
def fromFile(file: io.File, innerPath: String) = this.synchronized { def fromFile(file: io.File, innerPath: String) = ZipFileInputStreamFileSystem.synchronized {
Option(cache.get(file.getPath + ":" + innerPath, new Callable[ArchiveDirectory] { try {
def call = try { Option(cache.get(file.getPath + ":" + innerPath, new Callable[ArchiveDirectory] {
val zip = new ZipFile(file.getPath) def call = {
val cleanedPath = innerPath.stripPrefix("/").stripSuffix("/") + "/" val zip = new ZipFile(file.getPath)
val rootEntry = zip.getEntry(cleanedPath) val cleanedPath = innerPath.stripPrefix("/").stripSuffix("/") + "/"
val result = if (rootEntry != null && rootEntry.isDirectory) { val rootEntry = zip.getEntry(cleanedPath)
val directories = mutable.Set.empty[ArchiveDirectory] val result = if (rootEntry != null && rootEntry.isDirectory) {
val files = mutable.Set.empty[ArchiveFile] val directories = mutable.Set.empty[ArchiveDirectory]
val iterator = zip.entries() val files = mutable.Set.empty[ArchiveFile]
while (iterator.hasMoreElements) { val iterator = zip.entries()
val entry = iterator.nextElement() while (iterator.hasMoreElements) {
if (entry.getName.startsWith(cleanedPath)) { val entry = iterator.nextElement()
if (entry.isDirectory) directories += new ArchiveDirectory(entry, cleanedPath) if (entry.getName.startsWith(cleanedPath)) {
else files += new ArchiveFile(zip, entry, cleanedPath) if (entry.isDirectory) directories += new ArchiveDirectory(entry, cleanedPath)
} else files += new ArchiveFile(zip, entry, cleanedPath)
}
var root: ArchiveDirectory = null
for (entry <- directories ++ files) {
if (entry.path.length > 0) {
val parent = entry.path.substring(0, math.max(entry.path.lastIndexOf('/'), 0))
directories.find(d => d.path == parent) match {
case Some(directory) => directory.children += entry
case _ =>
} }
} }
else { var root: ArchiveDirectory = null
assert(entry.isInstanceOf[ArchiveDirectory]) for (entry <- directories ++ files) {
root = entry.asInstanceOf[ArchiveDirectory] if (entry.path.length > 0) {
val parent = entry.path.substring(0, math.max(entry.path.lastIndexOf('/'), 0))
directories.find(d => d.path == parent) match {
case Some(directory) => directory.children += entry
case _ =>
}
}
else {
assert(entry.isInstanceOf[ArchiveDirectory])
root = entry.asInstanceOf[ArchiveDirectory]
}
} }
root
} }
root else null
zip.close()
result
} }
else null })) match {
zip.close() case Some(archive) => new ZipFileInputStreamFileSystem(archive)
result case _ => null
} }
catch { }
case e: Throwable => catch {
OpenComputers.log.log(Level.WARNING, "Failed creating ZIP file system.", e) case e: Throwable =>
null OpenComputers.log.log(Level.WARNING, "Failed creating ZIP file system.", e)
} null
})) match {
case Some(archive) => new ZipFileInputStreamFileSystem(archive)
case _ => null
} }
} }

View File

@ -29,7 +29,6 @@ end
function os.setenv(varname, value) function os.setenv(varname, value)
checkArg(1, varname, "string") checkArg(1, varname, "string")
checkArg(2, value, "string", "nil")
env[varname] = value env[varname] = value
return env[varname] return env[varname]
end end

View File

@ -511,7 +511,7 @@ function shell.load(path, env, init, name)
return thread return thread
end end
function shell.register(thread) function shell.register(thread) -- called from coroutine.create
checkArg(1, thread, "thread") checkArg(1, thread, "thread")
if findProcess(thread) then if findProcess(thread) then
return false -- already attached somewhere return false -- already attached somewhere