diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/JarUserDataManager.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/JarUserDataManager.kt index 66492a2c1a1..9494c2ad888 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/JarUserDataManager.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/JarUserDataManager.kt @@ -24,6 +24,7 @@ import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.util.io.URLUtil import org.jetbrains.kotlin.idea.util.application.runReadAction +import java.util.concurrent.atomic.AtomicBoolean public object JarUserDataManager { enum class State { @@ -34,7 +35,7 @@ public object JarUserDataManager { val version = 2 - val fileAttributeService: FileAttributeService? = ServiceManager.getService(javaClass()) + val fileAttributeService: FileAttributeService? = ServiceManager.getService(FileAttributeService::class.java) public fun register(counter: JarBooleanPropertyCounter) { fileAttributeService?.register(counter.key.toString(), version) @@ -51,7 +52,7 @@ public object JarUserDataManager { } if (stored == null && fileAttributeService != null) { - val savedData = fileAttributeService.readAttribute(counter.key.toString(), localJarFile, javaClass()) + val savedData = fileAttributeService.readAttribute(counter.key.toString(), localJarFile, State::class.java) if (savedData != null && savedData.value != null) { val hasFileWithProperty = savedData.value == State.HAS_FILE @@ -77,6 +78,13 @@ public object JarUserDataManager { ApplicationManager.getApplication().executeOnPooledThread { runReadAction { + val data = localJarFile.getUserData(counter.key) + if (data != null && + ((data.hasFileWithProperty != null && localJarFile.timeStamp == data.timestamp) || !data.isProcessStarted.compareAndSet(false, true))) { + // Processing has started in some other thread or is already finished + return@runReadAction + } + val hasFileWithProperty = !VfsUtilCore.processFilesRecursively(jarFile) { file -> !counter.hasProperty(file) } @@ -96,7 +104,7 @@ public object JarUserDataManager { assert((timestamp == null) == (hasFileWithProperty == null)) { "Using empty timestamp is only allowed for storing not counted value" } localJarFile.putUserData(counter.key, - PropertyData(hasFileWithProperty, timestamp ?: localJarFile.timeStamp)) + PropertyData(hasFileWithProperty, timestamp ?: localJarFile.timeStamp, isProcessStarted = AtomicBoolean(false))) } object JarFileSystemUtil { @@ -122,7 +130,7 @@ public object JarUserDataManager { } } - data class PropertyData(val hasFileWithProperty: Boolean?, val timestamp: Long) + data class PropertyData(val hasFileWithProperty: Boolean?, val timestamp: Long, val isProcessStarted: AtomicBoolean) abstract class JarBooleanPropertyCounter(keyName: String) { val key: Key = Key.create(keyName)