Open files leak on incremental compilation fixed

#KT-25206 Fixed
This commit is contained in:
Andrey Uskov
2020-01-10 15:34:05 +03:00
parent 44edfc3717
commit e1d03e1f3a
4 changed files with 29 additions and 10 deletions
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.utils.Printer
import java.io.File import java.io.File
abstract class BasicMap<K : Comparable<K>, V>( abstract class BasicMap<K : Comparable<K>, V>(
storageFile: File, internal val storageFile: File,
keyDescriptor: KeyDescriptor<K>, keyDescriptor: KeyDescriptor<K>,
valueExternalizer: DataExternalizer<V> valueExternalizer: DataExternalizer<V>
) { ) {
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.utils.Printer
import java.io.File import java.io.File
abstract class BasicMap<K : Comparable<K>, V>( abstract class BasicMap<K : Comparable<K>, V>(
storageFile: File, internal val storageFile: File,
keyDescriptor: KeyDescriptor<K>, keyDescriptor: KeyDescriptor<K>,
valueExternalizer: DataExternalizer<V> valueExternalizer: DataExternalizer<V>
) { ) {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import java.io.File import java.io.File
import java.io.IOException
open class BasicMapsOwner(val cachesDir: File) { open class BasicMapsOwner(val cachesDir: File) {
private val maps = arrayListOf<BasicMap<*, *>>() private val maps = arrayListOf<BasicMap<*, *>>()
@@ -35,16 +36,35 @@ open class BasicMapsOwner(val cachesDir: File) {
} }
open fun clean() { open fun clean() {
maps.forEach { it.clean() } forEachMapSafe("clean", BasicMap<*, *>::clean)
} }
open fun close() { open fun close() {
maps.forEach { it.close() } forEachMapSafe("close", BasicMap<*, *>::close)
} }
open fun flush(memoryCachesOnly: Boolean) { open fun flush(memoryCachesOnly: Boolean) {
maps.forEach { it.flush(memoryCachesOnly) } forEachMapSafe("flush") { it.flush(memoryCachesOnly) }
} }
@TestOnly fun dump(): String = maps.joinToString("\n\n") { it.dump() } private fun forEachMapSafe(actionName: String, action: (BasicMap<*, *>) -> Unit) {
val actionExceptions = LinkedHashMap<String, Exception>()
maps.forEach {
try {
action(it)
} catch (e: Exception) {
actionExceptions[it.storageFile.name] = e
}
}
if (actionExceptions.isNotEmpty()) {
val desc = "Could not $actionName incremental caches in $cachesDir: ${actionExceptions.keys.joinToString(", ")}"
val allIOExceptions = actionExceptions.all { it is IOException }
val ex = if (allIOExceptions) IOException(desc) else Exception(desc)
actionExceptions.forEach { (_, e) -> ex.addSuppressed(e) }
throw ex
}
}
@TestOnly
fun dump(): String = maps.joinToString("\n\n") { it.dump() }
} }
@@ -79,11 +79,10 @@ class CachingLazyStorage<K, V>(
override fun clean() { override fun clean() {
try { try {
storage?.close() storage?.close()
} catch (ignored: Throwable) { } finally {
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
} }
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
} }
@Synchronized @Synchronized