[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
This commit is contained in:
Roman Shevchenko
2016-09-04 19:37:35 +03:00
parent 74af22eaae
commit 79d258ae47
5 changed files with 66 additions and 62 deletions
@@ -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);
}
}
@@ -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));
}
}
//<editor-fold desc="Deprecated stuff.">
/** @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);
}
//</editor-fold>
}
@@ -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);
}
}
};
+6 -4
View File
@@ -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)
+1 -1
View File
@@ -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!!