From c3e401de3261a915632dc100b3d15d70cf1c3b2f Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sat, 19 Oct 2024 10:07:53 +0200 Subject: [PATCH] IJPL-164182 make sure we execute ProjectRootManagerImpl.applyState only after any current modality dialog (cherry picked from commit 5d2be731fa7b095f7d7805788df5cbca123d33da) IJ-CR-147194 GitOrigin-RevId: 2828f1bea54e571a8793107e52940e6eaec07ae7 --- .../openapi/roots/impl/ProjectRootManagerComponent.kt | 11 ++++------- .../openapi/roots/impl/ProjectRootManagerImpl.kt | 11 ++++++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.kt b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.kt index 04897ee53068..3d299bfc119a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.kt +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.kt @@ -6,7 +6,6 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationListener import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.readAction -import com.intellij.openapi.components.ComponentManagerEx import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.diagnostic.trace @@ -38,7 +37,7 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager import com.intellij.platform.backend.workspace.WorkspaceModel import com.intellij.platform.workspace.storage.WorkspaceEntity import com.intellij.project.stateStore -import com.intellij.util.concurrency.ThreadingAssertions +import com.intellij.util.concurrency.annotations.RequiresReadLock import com.intellij.util.containers.CollectionFactory import com.intellij.util.indexing.EntityIndexingService import com.intellij.util.indexing.roots.WorkspaceIndexingRootsBuilder @@ -50,7 +49,6 @@ import com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileIndexEx import kotlinx.coroutines.* import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.TestOnly -import java.lang.Runnable import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock @@ -210,11 +208,10 @@ open class ProjectRootManagerComponent( postCollect(newDisposable, oldDisposable, watchRoots) } else { - @Suppress("UsagesOfObsoleteApi") - (project as ComponentManagerEx).getCoroutineScope().launch { + coroutineScope.launch { val job = launch(start = CoroutineStart.LAZY) { val watchRoots = readAction { collectWatchRoots(newDisposable) } - postCollect(newDisposable, oldDisposable, watchRoots) + postCollect(newDisposable = newDisposable, oldDisposable = oldDisposable, watchRoots = watchRoots) } collectWatchRootsJob.getAndSet(job)?.cancelAndJoin() job.start() @@ -268,8 +265,8 @@ open class ProjectRootManagerComponent( addRootsToWatch() } + @RequiresReadLock private fun collectWatchRoots(disposable: Disposable): Pair, Set> { - ThreadingAssertions. assertReadAccess() val recursivePaths = CollectionFactory.createFilePathSet() val flatPaths = CollectionFactory.createFilePathSet() WATCH_ROOTS_LOG.trace { "watch roots for ${project}}" } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.kt b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.kt index 30bc693f639b..ce82df7fbf6a 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.kt +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.kt @@ -23,7 +23,9 @@ import com.intellij.util.EventDispatcher import com.intellij.util.SmartList import com.intellij.util.io.URLUtil import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.jdom.Element import org.jetbrains.annotations.ApiStatus import org.jetbrains.jps.model.module.JpsModuleSourceRootType @@ -37,7 +39,7 @@ private const val ATTRIBUTE_VERSION = "version" @State(name = "ProjectRootManager") open class ProjectRootManagerImpl(val project: Project, - private val coroutineScope: CoroutineScope) : ProjectRootManagerEx(), PersistentStateComponent { + @JvmField protected val coroutineScope: CoroutineScope) : ProjectRootManagerEx(), PersistentStateComponent { private val projectJdkEventDispatcher = EventDispatcher.create(ProjectJdkListener::class.java) private var projectSdkName: String? = null private var projectSdkType: String? = null @@ -338,7 +340,10 @@ open class ProjectRootManagerImpl(val project: Project, if (app != null) { val isStateLoaded = isStateLoaded if (stateChanged) { - coroutineScope.launch(ModalityState.nonModal().asContextElement()) { + coroutineScope.launch { + // make sure we execute it only after any current modality dialog + withContext(Dispatchers.EDT + ModalityState.nonModal().asContextElement()) { + } applyState(isStateLoaded) } } @@ -349,7 +354,7 @@ open class ProjectRootManagerImpl(val project: Project, private suspend fun applyState(isStateLoaded: Boolean) { if (isStateLoaded) { LOG.debug("Run write action for projectJdkChanged()") - writeAction { + backgroundWriteAction { projectJdkChanged() } return