Allow parallel access to klib zip filesystem

This commit is contained in:
Alexander Gorshenev
2019-12-23 16:11:12 +03:00
committed by alexander-gorshenev
parent ddda93ad96
commit 9a12641fde
@@ -7,17 +7,27 @@ package org.jetbrains.kotlin.konan.file
import java.net.URI
import java.nio.file.*
import java.util.concurrent.ConcurrentHashMap
private val File.zipUri: URI
get() = URI.create("jar:${this.toPath().toUri()}")
private val counters = ConcurrentHashMap<FileSystem, Int>()
// Zip filesystem provider creates a singlton zip FileSystem.
// So newFileSystem can return an already existing one.
// And, more painful, closing the filesystem could close it for another consumer thread.
fun File.zipFileSystem(mutable: Boolean = false): FileSystem {
val zipUri = this.zipUri
val attributes = hashMapOf("create" to mutable.toString())
return try {
FileSystems.newFileSystem(zipUri, attributes, null)
FileSystems.newFileSystem(zipUri, attributes, null).also {
counters[it] = 1
}
} catch (e: FileSystemAlreadyExistsException) {
FileSystems.getFileSystem(zipUri)
FileSystems.getFileSystem(zipUri).also {
counters.computeIfPresent(it, { _, u -> u + 1})
}
}
}
@@ -46,7 +56,13 @@ fun <T> File.withZipFileSystem(mutable: Boolean = false, action: (FileSystem) ->
return try {
action(zipFileSystem)
} finally {
zipFileSystem.close()
val counter = counters[zipFileSystem]!!
if (counter == 1) {
zipFileSystem.close()
counters.remove(zipFileSystem)
} else {
counters.computeIfPresent(zipFileSystem, { _, u -> u - 1})
}
}
}