Allow parallel access to klib zip filesystem
This commit is contained in:
committed by
alexander-gorshenev
parent
ddda93ad96
commit
9a12641fde
@@ -7,17 +7,27 @@ package org.jetbrains.kotlin.konan.file
|
|||||||
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.file.*
|
import java.nio.file.*
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
private val File.zipUri: URI
|
private val File.zipUri: URI
|
||||||
get() = URI.create("jar:${this.toPath().toUri()}")
|
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 {
|
fun File.zipFileSystem(mutable: Boolean = false): FileSystem {
|
||||||
val zipUri = this.zipUri
|
val zipUri = this.zipUri
|
||||||
val attributes = hashMapOf("create" to mutable.toString())
|
val attributes = hashMapOf("create" to mutable.toString())
|
||||||
return try {
|
return try {
|
||||||
FileSystems.newFileSystem(zipUri, attributes, null)
|
FileSystems.newFileSystem(zipUri, attributes, null).also {
|
||||||
|
counters[it] = 1
|
||||||
|
}
|
||||||
} catch (e: FileSystemAlreadyExistsException) {
|
} 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 {
|
return try {
|
||||||
action(zipFileSystem)
|
action(zipFileSystem)
|
||||||
} finally {
|
} finally {
|
||||||
zipFileSystem.close()
|
val counter = counters[zipFileSystem]!!
|
||||||
|
if (counter == 1) {
|
||||||
|
zipFileSystem.close()
|
||||||
|
counters.remove(zipFileSystem)
|
||||||
|
} else {
|
||||||
|
counters.computeIfPresent(zipFileSystem, { _, u -> u - 1})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user