mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
It may happen that RunManagerImpl::loadState invokes Read Action (e.g. inside BuildArtifactsBeforeRunTaskBase.readExternal), so if we don't invoke the whole initialization under Read Action, we may get a deadlock if some other thread accesses RunManager (and triggers its initialization) under Write Action, or accesses it under Read Action while other Write Action is pending. GitOrigin-RevId: 8009acb892fbb3b1f24bd1b29db51d84d894db28
36 lines
1.7 KiB
Kotlin
36 lines
1.7 KiB
Kotlin
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
|
package com.intellij.execution.impl
|
|
|
|
import com.intellij.diagnostic.runActivity
|
|
import com.intellij.execution.RunManager
|
|
import com.intellij.execution.RunManager.Companion.IS_RUN_MANAGER_INITIALIZED
|
|
import com.intellij.openapi.application.readAction
|
|
import com.intellij.openapi.components.ComponentManagerEx
|
|
import com.intellij.openapi.module.ModuleManager
|
|
import com.intellij.openapi.project.Project
|
|
import com.intellij.openapi.project.impl.ProjectServiceContainerInitializedListener
|
|
import kotlinx.coroutines.async
|
|
|
|
private class ProjectRunConfigurationInitializer : ProjectServiceContainerInitializedListener {
|
|
override suspend fun execute(project: Project) {
|
|
project.coroutineScope.async {
|
|
if (IS_RUN_MANAGER_INITIALIZED.get(project) == true) {
|
|
return@async
|
|
}
|
|
|
|
// wait for module manager - may be required for module level run configurations
|
|
// it allows us to avoid thread blocking
|
|
// (RunManager itself cannot yet do the same, as platform doesn't provide non-blocking load state)
|
|
(project as ComponentManagerEx).getServiceAsync(ModuleManager::class.java).join()
|
|
|
|
runActivity("RunManager initialization") {
|
|
// we must not fire beginUpdate here, because message bus will fire queued parent message bus messages (and, so, SOE may occur because all other projectOpened will be processed before us)
|
|
// simply, you should not listen changes until project opened
|
|
readAction {
|
|
RunManager.getInstance(project)
|
|
}
|
|
IS_RUN_MANAGER_INITIALIZED.set(project, true)
|
|
}
|
|
}
|
|
}
|
|
} |