Fix locking multiple threads during KotlinConfiguration check

#KT-29892 Fixed
This commit is contained in:
Andrey Uskov
2019-03-28 13:23:17 +03:00
parent ff488bb871
commit 0f60daec25
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.idea.configuration.ui.notifications.notifyKotlinStyl
import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies
import org.jetbrains.kotlin.idea.versions.collectModulesWithOutdatedRuntime import org.jetbrains.kotlin.idea.versions.collectModulesWithOutdatedRuntime
import org.jetbrains.kotlin.idea.versions.findOutdatedKotlinLibraries import org.jetbrains.kotlin.idea.versions.findOutdatedKotlinLibraries
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
class KotlinConfigurationCheckerComponent(val project: Project) : ProjectComponent { class KotlinConfigurationCheckerComponent(val project: Project) : ProjectComponent {
@@ -44,13 +45,21 @@ class KotlinConfigurationCheckerComponent(val project: Project) : ProjectCompone
@Volatile @Volatile
private var notificationPostponed = false private var notificationPostponed = false
init { private val moduleRootListener = object : ModuleRootListener {
NotificationsConfiguration.getNotificationsConfiguration()
.register(CONFIGURE_NOTIFICATION_GROUP_ID, NotificationDisplayType.STICKY_BALLOON, true) private val checkInProgress = AtomicBoolean(false)
private val modulesUpdatedDuringCheck = AtomicBoolean(false)
val connection = project.messageBus.connect()
connection.subscribe(ProjectTopics.PROJECT_ROOTS, object : ModuleRootListener {
override fun rootsChanged(event: ModuleRootEvent) { override fun rootsChanged(event: ModuleRootEvent) {
try {
modulesUpdatedDuringCheck.set(true)
// forbid running multiple checks in parallel
if (!checkInProgress.compareAndSet(false, true)) return
// if during the execution of the current check the module list has updated, we should re-run this check
do {
modulesUpdatedDuringCheck.set(false)
if (!project.isInitialized) return if (!project.isInitialized) return
if (notificationPostponed && !isSyncing) { if (notificationPostponed && !isSyncing) {
@@ -69,8 +78,21 @@ class KotlinConfigurationCheckerComponent(val project: Project) : ProjectCompone
} }
checkHideNonConfiguredNotifications(project) checkHideNonConfiguredNotifications(project)
} while (
modulesUpdatedDuringCheck.get()
)
} finally {
checkInProgress.set(false)
} }
}) }
}
init {
NotificationsConfiguration.getNotificationsConfiguration()
.register(CONFIGURE_NOTIFICATION_GROUP_ID, NotificationDisplayType.STICKY_BALLOON, true)
val connection = project.messageBus.connect()
connection.subscribe(ProjectTopics.PROJECT_ROOTS, moduleRootListener)
connection.subscribe(ProjectDataImportListener.TOPIC, ProjectDataImportListener { connection.subscribe(ProjectDataImportListener.TOPIC, ProjectDataImportListener {
notifyOutdatedBundledCompilerIfNecessary(project) notifyOutdatedBundledCompilerIfNecessary(project)