mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[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:
@@ -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);
|
||||
}
|
||||
}
|
||||
+56
-55
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!!
|
||||
|
||||
Reference in New Issue
Block a user