From bed98927ed176e7146c61ea0c64fd06546ab7485 Mon Sep 17 00:00:00 2001 From: Michael Golubev Date: Tue, 11 Sep 2012 01:26:25 +0200 Subject: [PATCH] IDEA-91313 - Kill app server process on close --- .../execution/ui/RunContentManagerImpl.java | 87 ++++++++++++------- .../src/messages/ExecutionBundle.properties | 1 + 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index 3b1bff659f54..31091a7cab76 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -15,10 +15,7 @@ */ package com.intellij.execution.ui; -import com.intellij.execution.ExecutionBundle; -import com.intellij.execution.Executor; -import com.intellij.execution.ExecutorRegistry; -import com.intellij.execution.TerminateRemoteProcessDialog; +import com.intellij.execution.*; import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; @@ -35,6 +32,7 @@ import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerListener; @@ -566,7 +564,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { public void contentRemoveQuery(final ContentManagerEvent event) { if (event.getContent() == myContent) { - final boolean canClose = closeQuery(); + final boolean canClose = closeQuery(false); if (!canClose) { event.consume(); } @@ -588,7 +586,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { if (myContent == null) return true; - final boolean canClose = closeQuery(); + final boolean canClose = closeQuery(true); if (canClose) { myContent.getManager().removeContent(myContent, true); myContent = null; @@ -599,7 +597,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { public void projectClosing(final Project project) { } - private boolean closeQuery() { + private boolean closeQuery(boolean modal) { final RunContentDescriptor descriptor = getRunContentDescriptorByContent(myContent); if (descriptor == null) { @@ -628,14 +626,38 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { else { processHandler.detachProcess(); } - waitForProcess(descriptor); + waitForProcess(descriptor, modal); return true; } } - private void waitForProcess(final RunContentDescriptor descriptor) { - ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { - public void run() { + private void waitForProcess(final RunContentDescriptor descriptor, final boolean modal) { + final ProcessHandler processHandler = descriptor.getProcessHandler(); + final boolean killable = !modal && (processHandler instanceof KillableProcess) && ((KillableProcess)processHandler).canKillProcess(); + + String title = ExecutionBundle.message("terminating.process.progress.title", descriptor.getDisplayName()); + ProgressManager.getInstance().run(new Task.Backgroundable(myProject, title, true) { + + { + if (killable) { + String cancelText= ExecutionBundle.message("terminating.process.progress.kill"); + setCancelText(cancelText); + setCancelTooltipText(cancelText); + } + } + + @Override + public boolean isConditionalModal() { + return modal; + } + + @Override + public boolean shouldStartInBackground() { + return !modal; + } + + @Override + public void run(@NotNull final ProgressIndicator progressIndicator) { final Semaphore semaphore = new Semaphore(); semaphore.down(); @@ -653,31 +675,34 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { } }); - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - - if (progressIndicator != null) { - progressIndicator.setText(ExecutionBundle.message("waiting.for.vm.detach.progress.text")); - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - public void run() { - while (true) { - if (progressIndicator.isCanceled() || !progressIndicator.isRunning()) { - semaphore.up(); - break; - } - try { - synchronized (this) { - wait(2000L); - } - } - catch (InterruptedException ignore) { + progressIndicator.setText(ExecutionBundle.message("waiting.for.vm.detach.progress.text")); + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + public void run() { + while (true) { + if (progressIndicator.isCanceled() || !progressIndicator.isRunning()) { + semaphore.up(); + break; + } + try { + synchronized (this) { + wait(2000L); } } + catch (InterruptedException ignore) { + } } - }); - } + } + }); semaphore.waitFor(); } - }, ExecutionBundle.message("terminating.process.progress.title", descriptor.getDisplayName()), true, myProject); + + @Override + public void onCancel() { + if (killable && !processHandler.isProcessTerminated()) { + ((KillableProcess)processHandler).killProcess(); + } + } + }); } } diff --git a/platform/platform-resources-en/src/messages/ExecutionBundle.properties b/platform/platform-resources-en/src/messages/ExecutionBundle.properties index a7104caf1df1..a0d9889ec8fd 100644 --- a/platform/platform-resources-en/src/messages/ExecutionBundle.properties +++ b/platform/platform-resources-en/src/messages/ExecutionBundle.properties @@ -156,6 +156,7 @@ run.configuration.select.alternate.jre.label=Select Alternative JRE run.configuration.select.jre.dir.label=Select directory with JRE to run with run.configuration.arguments.help.panel.copy.action.name=Copy terminating.process.progress.title=Terminating ''{0}'' +terminating.process.progress.kill=Kill process waiting.for.vm.detach.progress.text=Waiting for process detach restart.error.message.title=Restart Error rerun.configuration.action.name=Rerun ''{0}''