From 06840b04d77e53e61c934b6cf985024ebd01a056 Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Mon, 29 Jun 2015 15:50:42 +0200 Subject: Target Explorer: Fix terminate of stopped process --- .../tcf/te/tcf/launch/cdt/utils/TERunProcess.java | 9 +- .../processes/core/launcher/ProcessLauncher.java | 106 ++++----------------- 2 files changed, 24 insertions(+), 91 deletions(-) diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TERunProcess.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TERunProcess.java index 35985155f..7c221f425 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TERunProcess.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TERunProcess.java @@ -55,7 +55,6 @@ public class TERunProcess extends PlatformObject implements IProcess, prName = remoteExePath; terminated = false; launch.addProcess(this); - fireCreationEvent(); EventManager.getInstance().addEventListener(this, ProcessStateChangeEvent.class); try { @@ -70,8 +69,7 @@ public class TERunProcess extends PlatformObject implements IProcess, reason = "Unknown Reason"; //$NON-NLS-1$ prName += " (Failed to start: " + reason + ')'; //$NON-NLS-1$ } - if (prLauncher == null) - fireTerminateEvent(); + fireCreationEvent(); } @Override @@ -113,8 +111,6 @@ public class TERunProcess extends PlatformObject implements IProcess, public void terminate() throws DebugException { if (!isTerminated()) { prLauncher.terminate(); - terminated = true; - fireTerminateEvent(); } } @@ -167,7 +163,8 @@ public class TERunProcess extends PlatformObject implements IProcess, if (pscEvent.getEventId().equals( ProcessStateChangeEvent.EVENT_PROCESS_CREATED)) { if ((pscEvent.getSource() instanceof ProcessContext)) { - context = (ProcessContext) pscEvent.getSource(); + if (prLauncher != null && prLauncher.getAdapter(ProcessContext.class) == pscEvent.getSource()) + context = (ProcessContext) pscEvent.getSource(); } } else if (pscEvent.getEventId().equals( ProcessStateChangeEvent.EVENT_PROCESS_TERMINATED)) { diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java index 0ce590eb4..6bce2ef40 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java @@ -91,6 +91,8 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher /* default */ IStreams svcStreams; // The remote process context /* default */ IProcesses.ProcessContext processContext; + // Whether SIGTERM has already been sent + /* default */ boolean sigTermSent; // The callback instance private ICallback callback; @@ -201,13 +203,24 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher if (channel != null && channel.getState() == IChannel.STATE_OPEN) { if (processContext != null && processContext.canTerminate()) { final IProcesses.ProcessContext finProcessContext = processContext; - // Try to terminate the process the usual way first (sending SIGTERM) - finProcessContext.terminate(new IProcesses.DoneCommand() { - @Override - public void doneCommand(IToken token, Exception error) { - onTerminateDone(finProcessContext, error); - } - }); + if (!sigTermSent) { + sigTermSent = true; + // Try to terminate the process the usual way first (sending SIGTERM) + finProcessContext.terminate(new IProcesses.DoneCommand() { + @Override + public void doneCommand(IToken token, Exception error) { + onTerminateDone(finProcessContext, error); + } + }); + } else { + // Terminate the process the hard way (sending SIGKILL) + getSvcProcesses().signal(processContext.getID(), 9, new IProcesses.DoneCommand() { + @Override + public void doneCommand(IToken token, Exception error) { + onTerminateDone(finProcessContext, error); + } + }); + } } } } @@ -256,84 +269,6 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher // Dispose the launcher directly dispose(); } - // No error from terminate, this does not mean that the process went down - // really -> SIGTERM might have been ignored from the process! - else { - final IProcesses.ProcessContext finContext = context; - // Let's see if we can still get information about the context - getSvcProcesses().getContext(context.getID(), new IProcesses.DoneGetContext() { - @Override - public void doneGetContext(IToken token, Exception error, ProcessContext context) { - // In case there is no error and we do get back an process context, - // the process must be still running, having ignored the SIGTERM. - if (error == null && context != null && context.getID().equals(finContext.getID())) { - // Let's send a SIGHUP next. - getSvcProcesses().signal(context.getID(), 15, new IProcesses.DoneCommand() { - @Override - public void doneCommand(IToken token, Exception error) { - onSignalSIGHUPDone(finContext, error); - } - }); - } - } - }); - } - } - - /** - * Check if the process context died after sending SIGHUP. - *
- * Called from {@link #onTerminateDone(IProcesses.ProcessContext, Exception)}.
- *
- * @param context The process context. Must not be null
.
- * @param error The exception in case sending the signal returned with an error or null
.
- */
- protected void onSignalSIGHUPDone(IProcesses.ProcessContext context, Exception error) {
- Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
- Assert.isNotNull(context);
-
- // If the terminate of the remote process context failed, give a warning to the user
- if (error != null) {
- String message = NLS.bind(Messages.ProcessLauncher_error_processSendSignalFailed, "SIGHUP(15)", context.getName()); //$NON-NLS-1$
- message += NLS.bind(Messages.ProcessLauncher_error_possibleCause, StatusHelper.unwrapErrorReport(error.getLocalizedMessage()));
-
- IStatus status = new Status(IStatus.WARNING, CoreBundleActivator.getUniqueIdentifier(), message, error);
- Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
-
- // Dispose the launcher directly
- dispose();
- }
- // No error from terminate, this does not mean that the process went down
- // really -> SIGTERM might have been ignored from the process!
- else {
- final IProcesses.ProcessContext finContext = context;
- // Let's see if we can still get information about the context
- getSvcProcesses().getContext(context.getID(), new IProcesses.DoneGetContext() {
- @Override
- public void doneGetContext(IToken token, Exception error, ProcessContext context) {
- // In case there is no error and we do get back an process context,
- // the process must be still running, having ignored the SIGHUP.
- if (error == null && context != null && context.getID().equals(finContext.getID())) {
- // Finally send a SIGKILL.
- getSvcProcesses().signal(context.getID(), 9, new IProcesses.DoneCommand() {
- @Override
- public void doneCommand(IToken token, Exception error) {
- if (error != null) {
- String message = NLS.bind(Messages.ProcessLauncher_error_processSendSignalFailed, "SIGKILL(15)", finContext.getName()); //$NON-NLS-1$
- message += NLS.bind(Messages.ProcessLauncher_error_possibleCause, StatusHelper.unwrapErrorReport(error.getLocalizedMessage()));
-
- IStatus status = new Status(IStatus.WARNING, CoreBundleActivator.getUniqueIdentifier(), message, error);
- Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
-
- // Dispose the launcher
- dispose();
- }
- }
- });
- }
- }
- });
- }
}
/* (non-Javadoc)
@@ -951,6 +886,7 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher
@Override
public void doneStart(IToken token, Exception error, ProcessContext process) {
activeToken = null;
+ sigTermSent = false;
if (error != null) {
// Construct the error message to show to the user
String message = NLS.bind(getProcessLaunchFailedMessageTemplate(),
--
cgit v1.2.3