diff options
author | Andrew Ferrazzutti | 2013-11-28 19:17:22 +0000 |
---|---|---|
committer | Sami Wagiaalla | 2014-01-08 16:15:07 +0000 |
commit | 44fd4a842d2af9e79cf811283ca3350ce7d13c1f (patch) | |
tree | 667bae893ad10e83b09c1436fbf752dc268a0a54 /systemtap | |
parent | 86506a2da696866d3837e6509c53600e094b0cdc (diff) | |
download | org.eclipse.linuxtools-44fd4a842d2af9e79cf811283ca3350ce7d13c1f.tar.gz org.eclipse.linuxtools-44fd4a842d2af9e79cf811283ca3350ce7d13c1f.tar.xz org.eclipse.linuxtools-44fd4a842d2af9e79cf811283ca3350ce7d13c1f.zip |
Systemtap: Integration with Debug view.
Allow SystemTap launches to be terminated, removed, relaunched
and put into console focus by the Debug View.
Also address some concurrency-related issues in ScriptConsole, and
add a "Remove Console" button to the ScriptConsole toolbar.
Change-Id: I700690fa6de1c7fab65d751557ebd7535dd27768
Signed-off-by: Andrew Ferrazzutti <aferrazz@redhat.com>
Reviewed-on: https://git.eclipse.org/r/20069
Tested-by: Hudson CI
Reviewed-by: Sami Wagiaalla <swagiaal@redhat.com>
IP-Clean: Sami Wagiaalla <swagiaal@redhat.com>
Tested-by: Sami Wagiaalla <swagiaal@redhat.com>
Diffstat (limited to 'systemtap')
19 files changed, 420 insertions, 66 deletions
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.structures/META-INF/MANIFEST.MF b/systemtap/org.eclipse.linuxtools.systemtap.structures/META-INF/MANIFEST.MF index 0750b4f4f1..969d044cd6 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.structures/META-INF/MANIFEST.MF +++ b/systemtap/org.eclipse.linuxtools.systemtap.structures/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %bundleName Bundle-SymbolicName: org.eclipse.linuxtools.systemtap.structures;singleton:=true -Bundle-Version: 2.1.0.qualifier +Bundle-Version: 2.2.0.qualifier Bundle-Vendor: %bundleProvider Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.linuxtools.systemtap.structures, @@ -16,4 +16,6 @@ Require-Bundle: org.eclipse.core.runtime, Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Localization: plugin Import-Package: com.jcraft.jsch;version="0.1.37", + org.eclipse.debug.core, + org.eclipse.debug.core.model, org.eclipse.linuxtools.tools.launch.core.factory diff --git a/systemtap/org.eclipse.linuxtools.systemtap.structures/pom.xml b/systemtap/org.eclipse.linuxtools.systemtap.structures/pom.xml index 76c2540cb0..6e0a0445e2 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.structures/pom.xml +++ b/systemtap/org.eclipse.linuxtools.systemtap.structures/pom.xml @@ -18,7 +18,7 @@ </parent> <artifactId>org.eclipse.linuxtools.systemtap.structures</artifactId> - <version>2.1.0-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <name>Linux Tools Structures Plug-in</name> diff --git a/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/process/SystemTapRuntimeProcessFactory.java b/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/process/SystemTapRuntimeProcessFactory.java new file mode 100644 index 0000000000..335630a44c --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/process/SystemTapRuntimeProcessFactory.java @@ -0,0 +1,50 @@ +package org.eclipse.linuxtools.systemtap.structures.process; + +import java.util.Map; + +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.IProcessFactory; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.core.model.IStreamsProxy; +import org.eclipse.debug.core.model.RuntimeProcess; + +/** + * @since 2.2 + */ +public class SystemTapRuntimeProcessFactory implements IProcessFactory { + + static public final String PROCESS_FACTORY_ID = "org.eclipse.linuxtools.systemtap.ui.ide.SystemTapRuntimeProcessFactory"; //$NON-NLS-1$ + + static public class SystemTapRuntimeProcess extends RuntimeProcess { + + private Process originalProcess = null; + + public SystemTapRuntimeProcess(ILaunch launch, Process process, + String name, Map attributes) { + super(launch, process, name, attributes); + originalProcess = process; + } + + public boolean matchesProcess(Process process) { + return originalProcess.equals(process); + } + + /** + * SystemTap scripts use a ScriptConsole instance as their output stream, + * so don't use the default stream. + */ + @Override + protected IStreamsProxy createStreamsProxy() { + return null; + } + + } + + @Override + public IProcess newProcess(ILaunch launch, Process process, String label, + Map attributes) { + + return new SystemTapRuntimeProcess(launch, process, label, attributes); + } + +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/runnable/Command.java b/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/runnable/Command.java index d1bb69c87a..2008957c8b 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/runnable/Command.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/runnable/Command.java @@ -208,7 +208,7 @@ public class Command implements Runnable { } /** - * Method to check whether or not the process in running. + * Method to check whether or not the process is running. * @return The execution status. */ public boolean isRunning() { @@ -354,4 +354,12 @@ public class Command implements Runnable { } } + /** + * @return The process of this command. + * @since 2.2 + */ + public Process getProcess() { + return process; + } + } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/META-INF/MANIFEST.MF b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/META-INF/MANIFEST.MF index 5812c73590..275d7752c6 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/META-INF/MANIFEST.MF +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/META-INF/MANIFEST.MF @@ -17,10 +17,12 @@ Require-Bundle: org.eclipse.ui, org.eclipse.ui.console;visibility:=reexport, org.eclipse.linuxtools.systemtap.ui.editor, org.eclipse.linuxtools.systemtap.structures, - com.jcraft.jsch;bundle-version="0.1.37" + com.jcraft.jsch;bundle-version="0.1.37", + org.eclipse.debug.ui Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: org.eclipse.core.resources, + org.eclipse.debug.ui, org.eclipse.linuxtools.systemtap.graphingapi.core.datasets, org.eclipse.linuxtools.systemtap.graphingapi.core.structures, org.eclipse.linuxtools.systemtap.graphingapi.ui.widgets, diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/icons/actions/progress_rem.gif b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/icons/actions/progress_rem.gif Binary files differnew file mode 100644 index 0000000000..2cd9c54443 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/icons/actions/progress_rem.gif diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/internal/systemtap/ui/consolelog/actions/CloseStapConsoleAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/internal/systemtap/ui/consolelog/actions/CloseStapConsoleAction.java new file mode 100644 index 0000000000..67c2308c0a --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/internal/systemtap/ui/consolelog/actions/CloseStapConsoleAction.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 Red Hat. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - initial implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.consolelog.actions; + +import org.eclipse.linuxtools.systemtap.ui.consolelog.internal.ConsoleLogPlugin; +import org.eclipse.linuxtools.systemtap.ui.consolelog.internal.Localization; +import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.ScriptConsole; +import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.ScriptConsole.ScriptConsoleObserver; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.console.ConsolePlugin; +import org.eclipse.ui.console.IConsole; + +public class CloseStapConsoleAction extends ConsoleAction implements ScriptConsoleObserver { + + @Override + public void run() { + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + @Override + public void run() { + if(null != console){ + ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new IConsole[]{console}); + } + } + }); + } + + public CloseStapConsoleAction(ScriptConsole fConsole) { + super(fConsole, + ConsoleLogPlugin.getDefault().getBundle().getEntry("icons/actions/progress_rem.gif"), //$NON-NLS-1$ + Localization.getString("action.closeConsole.name"), //$NON-NLS-1$ + Localization.getString("action.closeConsole.desc")); //$NON-NLS-1$ + setEnabled(false); + console.addScriptConsoleObserver(this); + } + + @Override + public void runningStateChanged(boolean running) { + setEnabled(!running); + } + +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/ScriptConsolePageParticipant.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/ScriptConsolePageParticipant.java index d9fb05f9c6..3132ddf89a 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/ScriptConsolePageParticipant.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/ScriptConsolePageParticipant.java @@ -9,21 +9,31 @@ package org.eclipse.linuxtools.systemtap.ui.consolelog; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.linuxtools.internal.systemtap.ui.consolelog.actions.CloseStapConsoleAction; import org.eclipse.linuxtools.internal.systemtap.ui.consolelog.actions.SaveLogAction; import org.eclipse.linuxtools.internal.systemtap.ui.consolelog.actions.StopScriptAction; +import org.eclipse.linuxtools.systemtap.structures.process.SystemTapRuntimeProcessFactory; import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.ScriptConsole; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleConstants; import org.eclipse.ui.console.IConsolePageParticipant; +import org.eclipse.ui.console.IConsoleView; import org.eclipse.ui.part.IPageBookViewPage; /** * This class is responsible for creating and initializing UI for a {@link ScriptConsole} * @since 2.0 */ -public class ScriptConsolePageParticipant implements IConsolePageParticipant { +public class ScriptConsolePageParticipant implements IConsolePageParticipant, IDebugContextListener { + private IPageBookViewPage fPage; + private IConsoleView fView; + private ScriptConsole fConsole; @Override @SuppressWarnings("rawtypes") @@ -37,22 +47,30 @@ public class ScriptConsolePageParticipant implements IConsolePageParticipant { return; } - ScriptConsole console = (ScriptConsole) iConsole; + fPage = page; + fConsole = (ScriptConsole) iConsole; + fView = (IConsoleView) fPage.getSite().getPage().findView(IConsoleConstants.ID_CONSOLE_VIEW); - StopScriptAction stopScriptAction = new StopScriptAction(console); - SaveLogAction saveLogAction = new SaveLogAction(console); + StopScriptAction stopScriptAction = new StopScriptAction(fConsole); + CloseStapConsoleAction closeConsoleAction = new CloseStapConsoleAction(fConsole); + SaveLogAction saveLogAction = new SaveLogAction(fConsole); // contribute to toolbar - IToolBarManager manager = page.getSite().getActionBars().getToolBarManager(); + IToolBarManager manager = fPage.getSite().getActionBars().getToolBarManager(); manager.appendToGroup(IConsoleConstants.LAUNCH_GROUP, stopScriptAction); + manager.appendToGroup(IConsoleConstants.LAUNCH_GROUP, closeConsoleAction); manager.appendToGroup(IConsoleConstants.OUTPUT_GROUP, saveLogAction); //TODO if {@link ModifyParsingAction} is restored, it is to be used here, //in the same way stopScriptAction and saveLogAction are used. + + DebugUITools.getDebugContextManager().getContextService(fPage.getSite().getWorkbenchWindow()).addDebugContextListener(this); } @Override public void dispose() { + DebugUITools.getDebugContextManager().getContextService(fPage.getSite().getWorkbenchWindow()).removeDebugContextListener(this); + fConsole = null; } @Override @@ -63,4 +81,21 @@ public class ScriptConsolePageParticipant implements IConsolePageParticipant { public void deactivated() { } + /** + * @since 3.0 + */ + @Override + public void debugContextChanged(DebugContextEvent event) { + if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) { + if (fView != null && fConsole != null) { + IProcess process = DebugUITools.getCurrentProcess(); + if (process != null && process instanceof SystemTapRuntimeProcessFactory.SystemTapRuntimeProcess + && ((SystemTapRuntimeProcessFactory.SystemTapRuntimeProcess) process) + .matchesProcess(fConsole.getProcess())) { + fView.display(fConsole); + } + } + } + } + } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/internal/localization.properties b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/internal/localization.properties index acb7526562..efeae3898b 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/internal/localization.properties +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/internal/localization.properties @@ -16,6 +16,9 @@ ErrorView.Line=Line action.stopScript.name=Stop Script action.stopScript.desc=Stop the script currently running in this console. +action.closeConsole.name=Close Console +action.closeConsole.desc=Close this console. + action.saveLog.name=Save &Log action.saveLog.desc=Save console log to file diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/structures/ScriptConsole.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/structures/ScriptConsole.java index 3a1dfd2710..ad5c0ee67a 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/structures/ScriptConsole.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.consolelog/src/org/eclipse/linuxtools/systemtap/ui/consolelog/structures/ScriptConsole.java @@ -25,6 +25,7 @@ import org.eclipse.linuxtools.systemtap.ui.consolelog.ScpExec; import org.eclipse.linuxtools.systemtap.ui.consolelog.internal.Localization; import org.eclipse.linuxtools.systemtap.ui.consolelog.views.ErrorView; import org.eclipse.linuxtools.tools.launch.core.factory.RuntimeProcessFactory; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IViewPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.console.ConsolePlugin; @@ -42,6 +43,7 @@ import org.eclipse.ui.console.IOConsole; */ public class ScriptConsole extends IOConsole { private static final long RETRY_STOP_TIME = 500; + private static final long JOIN_WAIT_TIME = 500; /** * The command that will run in this console. @@ -84,14 +86,16 @@ public class ScriptConsole extends IOConsole { private final LinkedList<ScriptConsoleObserver> activeConsoleObservers = new LinkedList<ScriptConsoleObserver>(); + private LinkedList<ScriptConsoleObserver> inactiveConsoleObservers + = new LinkedList<ScriptConsoleObserver>(); /** - * This method is used to get a reference to a <code>ScriptConsole</code>. If there + * This method is used to create a reference to a new <code>ScriptConsole</code>. If there * is already an console that has the same name as that provided it will be stopped, * cleared and returned to the caller to use. If there is no console matching the * provided name then a new <code>ScriptConsole</code> will be created for use. - * @param name The name of the console that should be returned if available. - * @return The console with the provided name, or a new instance if none exist. + * @param name The name of the console that should be created & returned. + * @return A console of the specified name, or <code>null</code> if there is an error. */ public static ScriptConsole getInstance(String name) { ScriptConsole console = null; @@ -107,17 +111,25 @@ public class ScriptConsole extends IOConsole { if(activeConsole.getName().endsWith(name)) { //Stop any script currently running, and terminate stream listeners. if (activeConsole.isRunning()) { - activeConsole.onCmdStopThread.interrupt(); activeConsole.stop(); if (activeConsole.errorDaemon != null) { activeConsole.cmd.removeErrorStreamListener(activeConsole.errorDaemon); } - activeConsole.cmd.removeInputStreamListener(activeConsole.consoleDaemon); + if (activeConsole.consoleDaemon != null) { + activeConsole.cmd.removeInputStreamListener(activeConsole.consoleDaemon); + } + } + if (activeConsole.onCmdStopThread != null && activeConsole.onCmdStopThread.isAlive()) { + activeConsole.onCmdStopThread.interrupt(); + try { + activeConsole.onCmdStopThread.join(JOIN_WAIT_TIME); + } catch (InterruptedException e) {} } //Remove output from last run activeConsole.clearConsole(); activeConsole.setName(name); console = activeConsole; + break; } } } @@ -195,6 +207,10 @@ public class ScriptConsole extends IOConsole { errorDaemon = new ErrorStreamDaemon(this, errorView, parser); } + private boolean waitingToStart() { + return onCmdStartThread != null && onCmdStartThread.isAlive(); + } + /** * Runs the provided command in this ScriptConsole instance. * @param command The command and arguments to run. @@ -204,7 +220,7 @@ public class ScriptConsole extends IOConsole { */ public void run(String[] command, String[] envVars, IErrorParser errorParser) { // Don't start a new command if one is already waiting to be started. - if (onCmdStartThread != null && onCmdStartThread.isAlive()) { + if (waitingToStart()) { return; } cmd = new ScpExec(command); @@ -217,12 +233,12 @@ public class ScriptConsole extends IOConsole { public void run() { ScpExec stop = new ScpExec(new String[]{stopString}); try { - do { - stop.start(); - synchronized (stopcmd) { + synchronized (stopcmd) { + while (stopcmd.isRunning()) { + stop.start(); stopcmd.wait(RETRY_STOP_TIME); } - } while (stopcmd.isRunning()); + } } catch (CoreException e) { // Failed to start the 'stop' process. Ignore. } catch (InterruptedException e) { @@ -256,7 +272,7 @@ public class ScriptConsole extends IOConsole { */ public void runLocally(String[] command, String[] envVars, IErrorParser errorParser, IProject project) { // Don't start a new command if one is already waiting to be started. - if (onCmdStartThread != null && onCmdStartThread.isAlive()) { + if (waitingToStart()) { return; } cmd = new Command(command, envVars, project); @@ -269,12 +285,12 @@ public class ScriptConsole extends IOConsole { @Override public void run() { try { - do { - RuntimeProcessFactory.getFactory().exec(stopString, null, proj); - synchronized (stopcmd) { + synchronized (stopcmd) { + while (stopcmd.isRunning()) { + RuntimeProcessFactory.getFactory().exec(stopString, null, proj); stopcmd.wait(RETRY_STOP_TIME); } - } while (stopcmd.isRunning()); + } } catch (IOException e) { ExceptionErrorDialog.openError(Localization.getString("ScriptConsole.ErrorKillingStap"), e); //$NON-NLS-1$ } catch (InterruptedException e) { @@ -291,9 +307,11 @@ public class ScriptConsole extends IOConsole { public void run() { try { synchronized (cmd) { - cmd.wait(); + while (cmd.isRunning()) { + cmd.wait(); + } + onCmdStopActions(); } - onCmdStopActions(); } catch (InterruptedException e) { return; } @@ -328,7 +346,7 @@ public class ScriptConsole extends IOConsole { } }; - if (errorParser != null) { + if (errorParser != null) { createErrorDaemon(errorParser); } activate(); @@ -340,9 +358,20 @@ public class ScriptConsole extends IOConsole { private final void onCmdStopActions() { notifyConsoleObservers(false); + final String name = super.getName(); + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + setName(Localization.getString("ScriptConsole.Terminated") + name); //$NON-NLS-1$ + } + }); } - void notifyConsoleObservers(boolean running){ + synchronized void notifyConsoleObservers(boolean running){ + for (ScriptConsoleObserver observer : inactiveConsoleObservers) { + activeConsoleObservers.remove(observer); + } + inactiveConsoleObservers = new LinkedList<ScriptConsoleObserver>(); for (ScriptConsoleObserver observer : activeConsoleObservers) { observer.runningStateChanged(running); } @@ -351,11 +380,20 @@ public class ScriptConsole extends IOConsole { /** * @since 2.0 */ - public void addScriptConsoleObserver (ScriptConsoleObserver observer){ + public synchronized void addScriptConsoleObserver(ScriptConsoleObserver observer){ activeConsoleObservers.add(observer); } /** + * @since 3.0 + */ + public synchronized void removeScriptConsoleObserver(ScriptConsoleObserver observer){ + if (activeConsoleObservers.contains(observer)) { + inactiveConsoleObservers.add(observer); + } + } + + /** * Check to see if the Command is still running * @return boolean representing if the command is running */ @@ -406,14 +444,23 @@ public class ScriptConsole extends IOConsole { } /** + * @return The process associated with this console's script when it is run. + * A <code>null</code> process indicates that the script has not yet started + * (if {@link #isRunning} returns true) or failed to start (if {@link #isRunning} is false). + * @since 3.0 + */ + public Process getProcess() { + return cmd != null ? cmd.getProcess() : null; + } + + /** * Stops the running command and the associated listeners. */ public synchronized void stop() { - if (isRunning() && (stopCommandThread == null || !stopCommandThread.isAlive())) { + if (isRunning() && getProcess() != null && (stopCommandThread == null || !stopCommandThread.isAlive())) { // Stop the underlying stap process stopCommandThread = new Thread(this.stopCommand); stopCommandThread.start(); - setName(Localization.getString("ScriptConsole.Terminated") + super.getName()); //$NON-NLS-1$ } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/META-INF/MANIFEST.MF b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/META-INF/MANIFEST.MF index 647461d9cb..238c717a4e 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/META-INF/MANIFEST.MF +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %bundleName Bundle-SymbolicName: org.eclipse.linuxtools.systemtap.ui.ide;singleton:=true -Bundle-Version: 2.2.0.qualifier +Bundle-Version: 2.3.0.qualifier Bundle-Activator: org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin Bundle-Vendor: %bundleProvider Bundle-Localization: plugin diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/plugin.xml b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/plugin.xml index fc650c9ef6..e989e90d1a 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/plugin.xml +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/plugin.xml @@ -363,6 +363,13 @@ </launchConfigurationType> </extension> <extension + point="org.eclipse.debug.core.processFactories"> + <processFactory + id="org.eclipse.linuxtools.systemtap.ui.ide.SystemTapRuntimeProcessFactory" + class="org.eclipse.linuxtools.systemtap.structures.process.SystemTapRuntimeProcessFactory"> + </processFactory> + </extension> + <extension point="org.eclipse.debug.ui.launchConfigurationTypeImages"> <launchConfigurationTypeImage configTypeID="org.eclipse.linuxtools.systemtap.ui.ide.SystemTapLaunchConfigurationType" diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/pom.xml b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/pom.xml index 7daf132621..87af6906da 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/pom.xml +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/pom.xml @@ -18,7 +18,7 @@ </parent> <artifactId>org.eclipse.linuxtools.systemtap.ui.ide</artifactId> - <version>2.2.0-SNAPSHOT</version> + <version>2.3.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <name>Linux Tools SystemTap IDE Plug-in</name> diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java index 36c6379e88..e615de8a7c 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java @@ -71,6 +71,7 @@ public class RunScriptChartHandler extends RunScriptHandler { } catch(WorkbenchException we) { ExceptionErrorDialog.openError(Messages.RunScriptChartAction_couldNotSwitchToGraphicPerspective, we); } + super.scriptConsoleInitialized(console); } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java index 9db6ab0edf..7f33f8280f 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java @@ -39,6 +39,7 @@ import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDESessionSettings; import org.eclipse.linuxtools.internal.systemtap.ui.ide.Localization; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.launcher.SystemTapScriptLaunch; import org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences.IDEPreferenceConstants; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.StapErrorParser; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary; @@ -83,6 +84,7 @@ public class RunScriptHandler extends AbstractHandler { private String serverfileName = null; private IPath path; private IProject project; + private SystemTapScriptLaunch launch; private final List<String> cmdList; @@ -109,6 +111,13 @@ public class RunScriptHandler extends AbstractHandler { } /** + * @since 2.3 + */ + public void setLaunch(SystemTapScriptLaunch launch){ + this.launch = launch; + } + + /** * Finds the editor containing the target script to run, so the script can be saved * when it is run, if appropriate. * The script is saved when it is run with the "simple" run button on the toolbar (path == null), @@ -165,42 +174,46 @@ public class RunScriptHandler extends AbstractHandler { findTargetEditor(); if(isValid()) { if(getRunLocal() == false) { - try{ - + try { ScpClient scpclient = new ScpClient(); serverfileName = fileName.substring(fileName.lastIndexOf('/')+1); tmpfileName="/tmp/"+ serverfileName; //$NON-NLS-1$ - scpclient.transfer(fileName,tmpfileName); - } catch (JSchException e) { - ErrorDialog.openError(PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getShell(), - Localization.getString("RunScriptHandler.serverError"), Localization.getString("RunScriptHandler.serverError"), //$NON-NLS-1$ //$NON-NLS-2$ - new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, Localization.getString("RunScriptHandler.checkCredentials"))); //$NON-NLS-1$ - return null; - } catch (IOException e) { - ExceptionErrorDialog.openError(Localization.getString("RunScriptHandler.ioError"), e); //$NON-NLS-1$ - return null; - } + scpclient.transfer(fileName,tmpfileName); + } catch (JSchException e) { + ErrorDialog.openError(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(), + Localization.getString("RunScriptHandler.serverError"), Localization.getString("RunScriptHandler.serverError"), //$NON-NLS-1$ //$NON-NLS-2$ + new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, Localization.getString("RunScriptHandler.checkCredentials"))); //$NON-NLS-1$ + return null; + } catch (IOException e) { + ExceptionErrorDialog.openError(Localization.getString("RunScriptHandler.ioError"), e); //$NON-NLS-1$ + return null; + } } final String[] script = buildStandardScript(); final String[] envVars = getEnvironmentVariables(); - if(continueRun) - { - Display.getDefault().asyncExec(new Runnable() { - @Override + if(continueRun) { + Display.getDefault().asyncExec(new Runnable() { + @Override public void run() { - final ScriptConsole console; - if(getRunLocal() == false) { - console = ScriptConsole.getInstance(serverfileName); - console.run(script, envVars, new StapErrorParser()); - } else { - console = ScriptConsole.getInstance(fileName); - console.runLocally(script, envVars, new StapErrorParser(), getProject()); - } - scriptConsoleInitialized(console); - } - }); - } + final ScriptConsole console; + boolean local = getRunLocal(); + if (!local) { + console = ScriptConsole.getInstance(serverfileName); + } else { + console = ScriptConsole.getInstance(fileName); + } + synchronized (console) { + if (!local) { + console.run(script, envVars, new StapErrorParser()); + } else { + console.runLocally(script, envVars, new StapErrorParser(), getProject()); + } + scriptConsoleInitialized(console); + } + } + }); + } } return null; @@ -213,6 +226,9 @@ public class RunScriptHandler extends AbstractHandler { * @since 2.0 */ protected void scriptConsoleInitialized(ScriptConsole console){ + if (launch != null && path != null) { + launch.setConsole(console); + } } /** diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java index 6928755f27..e7abe00ab0 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java @@ -89,6 +89,7 @@ public class Messages extends NLS { public static String SystemTapScriptLaunchError_graph; public static String SystemTapScriptLaunchError_fileNotFound; public static String SystemTapScriptLaunchError_fileNotStp; + public static String SystemTapScriptLaunchError_waitForConsoles; static { // initialize resource bundle diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunch.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunch.java new file mode 100644 index 0000000000..7cc3bb7b38 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunch.java @@ -0,0 +1,103 @@ +package org.eclipse.linuxtools.internal.systemtap.ui.ide.launcher; + +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.Launch; +import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.ScriptConsole; +import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.ScriptConsole.ScriptConsoleObserver; +import org.eclipse.swt.widgets.Display; + +public class SystemTapScriptLaunch extends Launch + implements ScriptConsoleObserver { + + private ScriptConsole console = null; + private boolean runStopped = false; + + public SystemTapScriptLaunch(ILaunchConfiguration launchConfiguration, String mode) { + super(launchConfiguration, mode, null); + } + + public void setConsole(ScriptConsole console) { + // If another launch is using the same console, remove that launch since + // ScriptConsole prevents two identical stap scripts from being be run at once. + this.console = console; + ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); + for (ILaunch launch : manager.getLaunches()) { + if (launch.equals(this)) { + continue; + } + if (launch instanceof SystemTapScriptLaunch) { + SystemTapScriptLaunch olaunch = (SystemTapScriptLaunch) launch; + if (olaunch.console == null || olaunch.console.equals(console)) { + olaunch.forceRemove(); + } + } + } + console.addScriptConsoleObserver(this); + } + + public ScriptConsole getConsole() { + return console; + } + + @Override + public void runningStateChanged(boolean running) { + DebugPlugin.newProcess(this, console.getCommand().getProcess(), console.getName()); + console.removeScriptConsoleObserver(this); + } + + @Override + public boolean canTerminate() { + if (runStopped) { + return false; + } + return console != null && !runStopped; + } + + @Override + public boolean isTerminated() { + if (!runStopped) { + if (super.isTerminated()) { + runStopped = true; + } + } + return runStopped; + } + + @Override + public void terminate() { + if (console != null) + { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + console.stop(); + } + }); + } + } + + @Override + public void launchRemoved(ILaunch launch) { + super.launchRemoved(launch); + if (launch.equals(this)) { + removeConsole(); + } + } + + private void removeConsole() { + if (console != null) { + console.removeScriptConsoleObserver(this); + console = null; + } + } + + private void forceRemove() { + runStopped = true; + removeConsole(); + ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); + manager.removeLaunch(this); + } +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java index 5890f36ef9..36808e36e5 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java @@ -24,8 +24,11 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.LaunchConfigurationDelegate; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.RunScriptChartHandler; @@ -34,6 +37,7 @@ import org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences.IDEPreferenc import org.eclipse.linuxtools.systemtap.graphingapi.core.datasets.IDataSet; import org.eclipse.linuxtools.systemtap.graphingapi.core.datasets.IDataSetParser; import org.eclipse.linuxtools.systemtap.graphingapi.core.structures.GraphData; +import org.eclipse.linuxtools.systemtap.structures.process.SystemTapRuntimeProcessFactory; import org.eclipse.linuxtools.systemtap.ui.consolelog.internal.ConsoleLogPlugin; import org.eclipse.linuxtools.systemtap.ui.consolelog.preferences.ConsoleLogPreferenceConstants; @@ -48,13 +52,24 @@ public class SystemTapScriptLaunchConfigurationDelegate extends * Keep a reference to the target running script's parent project, so only that project * will be saved when the script is run. */ - @Override - protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) { - return scriptProject; - } + @Override + protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) { + return scriptProject; + } + + @Override + public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) { + return new SystemTapScriptLaunch(configuration, mode); + } @Override public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { + // Force the configuration to use the proper Process Factory. + if (!configuration.getAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, "").equals(SystemTapRuntimeProcessFactory.PROCESS_FACTORY_ID)) { //$NON-NLS-1$ + ILaunchConfigurationWorkingCopy wc = configuration.getWorkingCopy(); + wc.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, SystemTapRuntimeProcessFactory.PROCESS_FACTORY_ID); + wc.doSave(); + } // Find the parent project of the target script. IPath path = Path.fromOSString(configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, (String)null)); IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path); @@ -75,6 +90,18 @@ public class SystemTapScriptLaunchConfigurationDelegate extends public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { + // Wait for other stap launches' consoles to be initiated before starting a new launch. + ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); + for (ILaunch olaunch : manager.getLaunches()) { + if (olaunch.equals(launch)) { + continue; + } + if (olaunch instanceof SystemTapScriptLaunch && ((SystemTapScriptLaunch) olaunch).getConsole() == null) { + throw new CoreException(new Status(IStatus.ERROR, getPluginID(), + Messages.SystemTapScriptLaunchError_waitForConsoles)); + } + } + if (!SystemTapScriptGraphOptionsTab.isValidLaunch(configuration)) { throw new CoreException(new Status(IStatus.ERROR, getPluginID(), Messages.SystemTapScriptLaunchError_graph)); } @@ -154,6 +181,7 @@ public class SystemTapScriptLaunchConfigurationDelegate extends action.addComandLineOptions(value); } + action.setLaunch((SystemTapScriptLaunch) launch); action.execute(null); } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties index f7894dfc4f..c8f38c93f8 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties @@ -83,3 +83,4 @@ SystemTapScriptOptionsTab_targetToolTip=Select a target executable to be passed SystemTapScriptLaunchError_graph=An error exists in this launch's graph settings. Please use the Run Configurations->Graphing menu to fix them. SystemTapScriptLaunchError_fileNotFound=No Systemtap script exists at the path {0}. Please use the Run Configurations->General menu to set the path of the script to run. SystemTapScriptLaunchError_fileNotStp={0} is not a Systemtap script file. Please use the Run Configurations->General menu to select a file with extension ".stp". +SystemTapScriptLaunchError_waitForConsoles=Please wait for all existing SystemTap launches to be initialized before starting another one.
\ No newline at end of file |