ensure that SaveAndSyncHandlerImpl task is not blocked if EDT used by modal progress dialog

GitOrigin-RevId: c93de3af6e7f0649807b4a238eaab3519a07e9b8
This commit is contained in:
Vladimir Krivosheev
2019-11-21 15:44:19 +00:00
committed by intellij-monorepo-bot
parent 17d244938e
commit 5dbf621074
7 changed files with 55 additions and 38 deletions
@@ -1,6 +1,7 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.openapi.application.AccessToken
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ComponentManager
@@ -22,6 +23,8 @@ internal class HeadlessSaveAndSyncHandler : BaseSaveAndSyncHandler() {
override fun unblockSyncOnFrameActivation() {}
override fun disableAutoSave() = AccessToken.EMPTY_ACCESS_TOKEN
override fun saveSettingsUnderModalProgress(componentManager: ComponentManager, isSaveAppAlso: Boolean): Boolean {
StoreUtil.saveSettings(componentManager, forceSavingAllSettings = true)
if (isSaveAppAlso && componentManager !== ApplicationManager.getApplication()) {
@@ -7,6 +7,7 @@ import com.intellij.ide.GeneralSettings
import com.intellij.ide.IdeEventQueue
import com.intellij.ide.SaveAndSyncHandler
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.AccessToken
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
@@ -74,6 +75,10 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable {
continue
}
if (blockSaveOnFrameDeactivationCount.get() > 0 || ProgressManager.getInstance().hasModalProgressIndicator()) {
return
}
LOG.runAndLogException {
runBlocking {
coroutineScope {
@@ -203,7 +208,7 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable {
}
var isSavedSuccessfully = true
runInSaveOnFrameDeactivationDisabledMode {
runInAutoSaveDisabledMode {
edtPoolDispatcherManager.processTasks()
ProgressManager.getInstance().run(object : Task.Modal(componentManager as? Project, "Saving " + (if (componentManager is Application) "Application" else "Project"), /* canBeCancelled = */ false) {
@@ -290,6 +295,15 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable {
}
}
override fun disableAutoSave(): AccessToken {
blockSaveOnFrameDeactivation()
return object : AccessToken() {
override fun finish() {
unblockSaveOnFrameDeactivation()
}
}
}
override fun blockSaveOnFrameDeactivation() {
LOG.debug("save blocked")
blockSaveOnFrameDeactivationCount.incrementAndGet()
@@ -1,6 +1,7 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide
import com.intellij.openapi.application.AccessToken
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.components.ComponentManager
@@ -53,6 +54,8 @@ abstract class SaveAndSyncHandler {
abstract fun refreshOpenFiles()
abstract fun disableAutoSave(): AccessToken
abstract fun blockSaveOnFrameDeactivation()
abstract fun unblockSaveOnFrameDeactivation()
@@ -168,13 +168,8 @@ private suspend fun saveAllProjects(forceSavingAllSettings: Boolean) {
}
}
inline fun runInSaveOnFrameDeactivationDisabledMode(task: () -> Unit) {
val saveAndSyncManager = SaveAndSyncHandler.getInstance()
saveAndSyncManager.blockSaveOnFrameDeactivation()
try {
inline fun runInAutoSaveDisabledMode(task: () -> Unit) {
SaveAndSyncHandler.getInstance().disableAutoSave().use {
task()
}
finally {
saveAndSyncManager.unblockSaveOnFrameDeactivation()
}
}
@@ -1,7 +1,7 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.wm.impl
import com.intellij.configurationStore.runInSaveOnFrameDeactivationDisabledMode
import com.intellij.configurationStore.runInAutoSaveDisabledMode
import com.intellij.ide.AppLifecycleListener
import com.intellij.ide.GeneralSettings
import com.intellij.ide.SaveAndSyncHandler
@@ -39,7 +39,7 @@ open class CloseProjectWindowHelper {
protected open fun getNumberOfOpenedProjects() = ProjectManager.getInstance().openProjects.size
protected open fun closeProjectAndShowWelcomeFrameIfNoProjectOpened(project: Project?) {
runInSaveOnFrameDeactivationDisabledMode {
runInAutoSaveDisabledMode {
if (project != null && project.isOpen) {
ProjectManagerEx.getInstanceEx().closeAndDispose(project)
}
@@ -11,6 +11,7 @@ import com.intellij.ide.impl.OpenProjectTask;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.ide.lightEdit.LightEditUtil;
import com.intellij.ide.util.PsiNavigationSupport;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
@@ -188,22 +189,13 @@ public final class PlatformProjectOpenProcessor extends ProjectOpenProcessor imp
}
}
SaveAndSyncHandler saveAndSyncHandler = ApplicationManager.getApplication().getServiceIfCreated(SaveAndSyncHandler.class);
if (saveAndSyncHandler != null) {
saveAndSyncHandler.blockSyncOnFrameActivation();
}
try {
try (AccessToken ignored = SaveAndSyncHandler.getInstance().disableAutoSave()) {
Project project = openExistingProject(file, baseDir, options);
if (project != null && file != baseDir && !Files.isDirectory(file)) {
openFileFromCommandLine(project, file, line);
}
return project;
}
finally {
if (saveAndSyncHandler != null) {
saveAndSyncHandler.unblockSyncOnFrameActivation();
}
}
}
@Nullable
@@ -211,9 +203,13 @@ public final class PlatformProjectOpenProcessor extends ProjectOpenProcessor imp
public static Project openExistingProject(@NotNull Path file,
@Nullable("null for IPR project") Path projectDir,
@NotNull OpenProjectTask options) {
if (options.getProject() != null && ProjectManagerEx.getInstanceEx().isProjectOpened(options.getProject())) {
return null;
if (options.getProject() != null) {
ProjectManagerEx projectManager = ProjectManagerEx.getInstanceExIfCreated();
if (projectManager != null && projectManager.isProjectOpened(options.getProject())) {
return null;
}
}
Activity activity = StartUpMeasurer.startMainActivity("project opening preparation");
if (!options.forceOpenInNewFrame) {
Project[] openProjects = ProjectUtil.getOpenProjects();
@@ -1,6 +1,7 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.platform
import com.intellij.configurationStore.runInAutoSaveDisabledMode
import com.intellij.conversion.CannotConvertException
import com.intellij.diagnostic.ActivityCategory
import com.intellij.diagnostic.runActivity
@@ -29,7 +30,9 @@ import java.nio.file.Path
internal open class ProjectFrameAllocator {
open fun run(task: Runnable): Boolean {
task.run()
runInAutoSaveDisabledMode {
task.run()
}
return true
}
@@ -58,23 +61,26 @@ internal class ProjectUiFrameAllocator(private var options: OpenProjectTask, pri
override fun run(task: Runnable): Boolean {
var completed = false
ApplicationManager.getApplication().invokeAndWait {
val frame = createFrameIfNeeded()
completed = ProgressManager.getInstance().runProcessWithProgressSynchronously({
if (frameHelper == null) {
ApplicationManager.getApplication().invokeLater {
if (cancelled) {
return@invokeLater
runInAutoSaveDisabledMode {
ApplicationManager.getApplication().invokeAndWait {
val frame = createFrameIfNeeded()
completed = ProgressManager.getInstance().runProcessWithProgressSynchronously(
{
if (frameHelper == null) {
ApplicationManager.getApplication().invokeLater {
if (cancelled) {
return@invokeLater
}
runActivity("project frame initialization") {
initNewFrame(frame)
}
}
}
runActivity("project frame initialization") {
initNewFrame(frame)
}
}
}
task.run()
}, "Loading ${projectFile.fileName} Project", true, null, frame.rootPane)
task.run()
}, "Loading ${projectFile.fileName} Project", true, null, frame.rootPane)
}
}
return completed
}