From 79d258ae4725809ceb06b4f996c41e5ef256e5f7 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Sun, 4 Sep 2016 19:37:35 +0300 Subject: [PATCH] [platform] ApplicationImpl.exit() corrections - combines actual implementations into a single method - fixes premature clearing of the "exit-in-progress" flag - gets rid of a duplicate option --- .../openapi/application/ex/ApplicationEx.java | 3 +- .../application/impl/ApplicationImpl.java | 111 +++++++++--------- .../src/com/intellij/ui/AppUIUtil.java | 2 +- plugins/settings-repository/src/autoSync.kt | 10 +- plugins/settings-repository/src/sync.kt | 2 +- 5 files changed, 66 insertions(+), 62 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java index 337dd04eb83a..7561f8fdd530 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java +++ b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java @@ -125,6 +125,7 @@ public interface ApplicationEx extends Application { void assertTimeConsuming(); @Deprecated // todo to be removed in IDEA 17 + @SuppressWarnings("unused") void runEdtSafeAction(@NotNull Runnable runnable); /** @@ -133,4 +134,4 @@ public interface ApplicationEx extends Application { * @return true if action was run while holding the lock, false if was unable to get the lock and action was not run */ boolean tryRunReadAction(@NotNull Runnable action); -} +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 1029f4210213..cb9d1c500dd1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -113,6 +113,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App @Nullable private Splash mySplash; private boolean myDoNotSave; + private volatile boolean myExitInProgress; private volatile boolean myDisposeInProgress; private final Disposable myLastDisposable = Disposer.newDisposable(); // will be disposed last @@ -706,7 +707,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App @Override public void exit(boolean force, final boolean exitConfirmed) { - exit(false, exitConfirmed, true, false); + exit(false, exitConfirmed, false); } @Override @@ -715,8 +716,8 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App } @Override - public void restart(final boolean exitConfirmed) { - exit(false, exitConfirmed, true, true); + public void restart(boolean exitConfirmed) { + exit(false, exitConfirmed, true); } /** @@ -728,66 +729,58 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App * Note: there are possible scenarios when we get a quit notification at a moment when another * quit message is shown. In that case, showing multiple messages sounds contra-intuitive as well */ - private static volatile boolean exiting; - - public void exit(final boolean force, final boolean exitConfirmed, final boolean allowListenersToCancel, final boolean restart) { - if (!force && exiting) { - return; + public void exit(boolean force, boolean exitConfirmed, boolean restart) { + if (!force) { + if (myExitInProgress) return; + if (!exitConfirmed && getDefaultModalityState() != ModalityState.NON_MODAL) return; } - exiting = true; - try { - if (!force && !exitConfirmed && getDefaultModalityState() != ModalityState.NON_MODAL) { - return; - } - - Runnable runnable = () -> { - if (!force && !confirmExitIfNeeded(exitConfirmed)) { - saveAll(); - return; - } - - getMessageBus().syncPublisher(AppLifecycleListener.TOPIC).appClosing(); - myDisposeInProgress = true; - doExit(allowListenersToCancel, restart); - myDisposeInProgress = false; - }; - - if (isDispatchThread()) { - runnable.run(); - } - else { - invokeLater(runnable, ModalityState.NON_MODAL); - } + myExitInProgress = true; + if (isDispatchThread()) { + doExit(force, exitConfirmed, restart); } - finally { - exiting = false; + else { + invokeLater(() -> doExit(force, exitConfirmed, restart), ModalityState.NON_MODAL); } } - private boolean doExit(boolean allowListenersToCancel, boolean restart) { - saveSettings(); - - if (allowListenersToCancel && !canExit()) { - return false; - } - - final boolean success = disposeSelf(allowListenersToCancel); - if (!success || isUnitTestMode()) { - return false; - } - - int exitCode = 0; - if (restart && Restarter.isSupported()) { - try { - exitCode = Restarter.scheduleRestart(); + private void doExit(boolean force, boolean exitConfirmed, boolean restart) { + try { + if (!force && !confirmExitIfNeeded(exitConfirmed)) { + saveAll(); + return; } - catch (IOException e) { - LOG.warn("Cannot restart", e); + + getMessageBus().syncPublisher(AppLifecycleListener.TOPIC).appClosing(); + + myDisposeInProgress = true; + + saveSettings(); + + if (!force && !canExit()) { + return; } + + boolean success = disposeSelf(!force); + if (!success || isUnitTestMode()) { + return; + } + + int exitCode = 0; + if (restart && Restarter.isSupported()) { + try { + exitCode = Restarter.scheduleRestart(); + } + catch (IOException e) { + LOG.warn("Cannot restart", e); + } + } + System.exit(exitCode); + } + finally { + myDisposeInProgress = false; + myExitInProgress = false; } - System.exit(exitCode); - return true; } private static boolean confirmExitIfNeeded(boolean exitConfirmed) { @@ -1362,4 +1355,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App myDispatcher.getListeners().removeAll(listeners); Disposer.register(disposable, () -> myDispatcher.getListeners().addAll(listeners)); } -} + + // + /** @deprecated duplicate parameters; use {@link #exit(boolean, boolean, boolean)} instead (to be removed in IDEA 17) */ + @SuppressWarnings("unused") + public void exit(boolean force, boolean exitConfirmed, boolean allowListenersToCancel, boolean restart) { + exit(force, exitConfirmed, restart); + } + // +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java index 8404c7c0cb80..9f68be2fd150 100644 --- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java @@ -291,7 +291,7 @@ public class AppUIUtil { System.exit(Main.PRIVACY_POLICY_REJECTION); } else { - ((ApplicationImpl)application).exit(true, true, false, false); + ((ApplicationImpl)application).exit(true, true, false); } } }; diff --git a/plugins/settings-repository/src/autoSync.kt b/plugins/settings-repository/src/autoSync.kt index effd6d9c9df2..a23c1ed37e4e 100644 --- a/plugins/settings-repository/src/autoSync.kt +++ b/plugins/settings-repository/src/autoSync.kt @@ -145,9 +145,12 @@ internal class AutoSyncManager(private val icsManager: IcsManager) { app.invokeAndWait({ catchAndLog { val updateResult = updater.merge() - if (!onAppExit && !app.isDisposeInProgress && updateResult != null && updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult, app.messageBus)) { + if (!onAppExit && + !app.isDisposeInProgress && + updateResult != null && + updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult, app.messageBus)) { // force to avoid saveAll & confirmation - app.exit(true, true, true, true) + app.exit(true, true, true) } } }, ModalityState.NON_MODAL) @@ -164,8 +167,7 @@ inline internal fun catchAndLog(asWarning: Boolean = false, runnable: () -> Unit try { runnable() } - catch (e: ProcessCanceledException) { - } + catch (e: ProcessCanceledException) { } catch (e: Throwable) { if (asWarning || e is AuthenticationException || e is NoRemoteRepositoryException) { LOG.warn(e) diff --git a/plugins/settings-repository/src/sync.kt b/plugins/settings-repository/src/sync.kt index 7daa47d396b6..94e9d6261169 100644 --- a/plugins/settings-repository/src/sync.kt +++ b/plugins/settings-repository/src/sync.kt @@ -133,7 +133,7 @@ internal class SyncManager(private val icsManager: IcsManager, private val autoS if (restartApplication) { // force to avoid saveAll & confirmation - (ApplicationManager.getApplication() as ApplicationImpl).exit(true, true, true, true) + (ApplicationManager.getApplication() as ApplicationImpl).exit(true, true, true) } else if (exception != null) { throw exception!!