1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-12 18:55:38 +02:00

Bug 289526 - [debug view] Migrate the Restart feature to the new one, as supported by the platform

This commit is contained in:
Pawel Piech 2010-04-29 22:45:45 +00:00
parent 9acd76c5b0
commit 718f11adef
5 changed files with 165 additions and 101 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2000, 2006 QNX Software Systems and others. * Copyright (c) 2000, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* QNX Software Systems - Initial API and implementation * QNX Software Systems - Initial API and implementation
* Navid Mehregani (TI) - Bug 289526 - Migrate the Restart feature to the new one, as supported by the platform
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.debug.core.model; package org.eclipse.cdt.debug.core.model;
@ -15,6 +16,8 @@ import org.eclipse.debug.core.DebugException;
/** /**
* Provides the ability to restart a debug target. * Provides the ability to restart a debug target.
* *
* @deprecated Use org.eclipse.debug.core.commands.IRestartHandler instead. IRestartHandler
* handles the call in an asynchronous fashion.
*/ */
public interface IRestart public interface IRestart
{ {

View file

@ -372,12 +372,14 @@
</propertyTester> </propertyTester>
</extension> </extension>
<!-- Bug 289526 [debug view] Migrate the Restart feature to the new one, as supported by the platform
<extension Don't contribute this action to context menu if selection isn't an IRestart. Debug platform
already contributes it. -->
<extension
point="org.eclipse.ui.popupMenus"> point="org.eclipse.ui.popupMenus">
<viewerContribution <viewerContribution
targetID="org.eclipse.debug.ui.DebugView" targetID="org.eclipse.debug.ui.DebugView"
id="org.eclipse.cdt.debug.ui.debugview.popupMenu"> id="org.eclipse.cdt.debug.ui.debugview.popupMenu2">
<action <action
label="%RestartAction.label" label="%RestartAction.label"
icon="icons/elcl16/restart.gif" icon="icons/elcl16/restart.gif"
@ -387,7 +389,20 @@
enablesFor="1" enablesFor="1"
id="org.eclipse.cdt.debug.internal.ui.actions.RestartActionDelegate"> id="org.eclipse.cdt.debug.internal.ui.actions.RestartActionDelegate">
<selection class="org.eclipse.cdt.debug.core.model.IRestart"/> <selection class="org.eclipse.cdt.debug.core.model.IRestart"/>
</action> </action>
<visibility>
<objectClass name="org.eclipse.cdt.debug.core.model.IRestart"/>
</visibility>
</viewerContribution>
</extension>
<extension
point="org.eclipse.ui.popupMenus">
<viewerContribution
targetID="org.eclipse.debug.ui.DebugView"
id="org.eclipse.cdt.debug.ui.debugview.popupMenu">
<action <action
state="false" state="false"
style="toggle" style="toggle"
@ -877,18 +892,6 @@
<viewContribution <viewContribution
targetID="org.eclipse.debug.ui.DebugView" targetID="org.eclipse.debug.ui.DebugView"
id="org.eclipse.cdt.debug.ui.debugview.toolbar"> id="org.eclipse.cdt.debug.ui.debugview.toolbar">
<action
id="org.eclipse.cdt.debug.internal.ui.actions.RestartActionDelegate"
toolbarPath="threadGroup"
class="org.eclipse.cdt.debug.internal.ui.actions.RestartActionDelegate"
disabledIcon="icons/dlcl16/restart.gif"
enablesFor="1"
icon="icons/elcl16/restart.gif"
helpContextId="restart_action_context"
label="%RestartAction.label"
tooltip="%RestartAction.tooltip">
<selection class="org.eclipse.cdt.debug.core.model.IRestart"/>
</action>
<action <action
state="false" state="false"
style="toggle" style="toggle"

View file

@ -1,43 +1,84 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2006 QNX Software Systems and others. * Copyright (c) 2004, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* QNX Software Systems - Initial API and implementation * QNX Software Systems - Initial API and implementation
* Navid Mehregani (TI) - Bug 289526 - Migrate the Restart feature to the new one, as supported by the platform
* Wind River Systems - Bug 289526 - Additional fixes
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.actions; package org.eclipse.cdt.debug.internal.ui.actions;
import org.eclipse.cdt.debug.core.model.IRestart; import org.eclipse.cdt.debug.core.model.IRestart;
import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.commands.IRestartHandler;
import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.internal.ui.commands.actions.RestartCommandAction;
import org.eclipse.jface.action.IAction;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchWindow;
/** /**
* The delegate of the "Restart" action. * The delegate of the "Restart" action.
*/ */
public class RestartActionDelegate extends AbstractListenerActionDelegate { public class RestartActionDelegate extends AbstractListenerActionDelegate {
private RestartCommandAction fRestartCommandAction;
@Override
public void init(IAction action) {
setAction(action);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.actions.AbstractDebugActionDelegate#doAction(java.lang.Object) * @see org.eclipse.cdt.debug.internal.ui.actions.AbstractDebugActionDelegate#doAction(java.lang.Object)
*/ */
protected void doAction( Object element ) throws DebugException { protected void doAction( Object element ) throws DebugException {
IRestart restartTarget = getRestartTarget( element ); IRestartHandler asynchronousRestartHandler = getAsynchronousRestartHandler( element );
if ( restartTarget != null ) { if (asynchronousRestartHandler!=null && fRestartCommandAction!=null ) {
restartTarget.restart(); fRestartCommandAction.run();
} else {
IRestart restartTarget = getRestartTarget( element );
if ( restartTarget != null ) {
restartTarget.restart();
}
} }
} }
@Override
public void init(IViewPart view) {
super.init(view);
fRestartCommandAction = new RestartCommandAction();
fRestartCommandAction.setActionProxy(getAction());
fRestartCommandAction.init(getView());
}
@Override
public void init(IWorkbenchWindow window) {
super.init(window);
fRestartCommandAction = new RestartCommandAction();
fRestartCommandAction.setActionProxy(getAction());
fRestartCommandAction.init(getWindow());
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.actions.AbstractDebugActionDelegate#isEnabledFor(java.lang.Object) * @see org.eclipse.cdt.debug.internal.ui.actions.AbstractDebugActionDelegate#isEnabledFor(java.lang.Object)
*/ */
protected boolean isEnabledFor( Object element ) { protected boolean isEnabledFor( Object element ) {
IRestart restartTarget = getRestartTarget( element ); IRestartHandler asynchronousRestartHandler = getAsynchronousRestartHandler( element );
if ( restartTarget != null ) { if (asynchronousRestartHandler!=null && fRestartCommandAction!=null) {
return checkCapability( restartTarget ); return fRestartCommandAction.isEnabled();
} else {
IRestart restartTarget = getRestartTarget( element );
if ( restartTarget != null ) {
return checkCapability( restartTarget );
}
} }
return false; return false;
} }
@ -79,6 +120,13 @@ public class RestartActionDelegate extends AbstractListenerActionDelegate {
return (IRestart)((IAdaptable)element).getAdapter( IRestart.class ); return (IRestart)((IAdaptable)element).getAdapter( IRestart.class );
return getDefaultRestartTarget( element ); return getDefaultRestartTarget( element );
} }
protected IRestartHandler getAsynchronousRestartHandler( Object element ) {
if ( element instanceof IAdaptable )
return (IRestartHandler)((IAdaptable)element).getAdapter( IRestartHandler.class );
return null;
}
private IRestart getDefaultRestartTarget( Object element ) { private IRestart getDefaultRestartTarget( Object element ) {
if ( element instanceof IDebugElement ) { if ( element instanceof IDebugElement ) {

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Wind River Systems - initial API and implementation * Wind River Systems - initial API and implementation
* Navid Mehregani (TI) - Bug 289526 - Migrate the Restart feature to the new one, as supported by the platform
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui; package org.eclipse.cdt.dsf.gdb.internal.ui;
@ -16,7 +17,6 @@ import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint;
import org.eclipse.cdt.debug.core.model.IRestart;
import org.eclipse.cdt.debug.core.model.IResumeWithoutSignalHandler; import org.eclipse.cdt.debug.core.model.IResumeWithoutSignalHandler;
import org.eclipse.cdt.debug.core.model.IReverseResumeHandler; import org.eclipse.cdt.debug.core.model.IReverseResumeHandler;
import org.eclipse.cdt.debug.core.model.IReverseStepIntoHandler; import org.eclipse.cdt.debug.core.model.IReverseStepIntoHandler;
@ -68,6 +68,7 @@ import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchesListener2; import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.debug.core.commands.IDisconnectHandler; import org.eclipse.debug.core.commands.IDisconnectHandler;
import org.eclipse.debug.core.commands.IRestartHandler;
import org.eclipse.debug.core.commands.IResumeHandler; import org.eclipse.debug.core.commands.IResumeHandler;
import org.eclipse.debug.core.commands.IStepIntoHandler; import org.eclipse.debug.core.commands.IStepIntoHandler;
import org.eclipse.debug.core.commands.IStepOverHandler; import org.eclipse.debug.core.commands.IStepOverHandler;
@ -181,7 +182,7 @@ public class GdbAdapterFactory
session.registerModelAdapter(IResumeHandler.class, fResumeCommand); session.registerModelAdapter(IResumeHandler.class, fResumeCommand);
session.registerModelAdapter(IReverseResumeHandler.class, fReverseResumeCommand); session.registerModelAdapter(IReverseResumeHandler.class, fReverseResumeCommand);
session.registerModelAdapter(IResumeWithoutSignalHandler.class, fResumeWithoutSignalCommand); session.registerModelAdapter(IResumeWithoutSignalHandler.class, fResumeWithoutSignalCommand);
session.registerModelAdapter(IRestart.class, fRestartCommand); session.registerModelAdapter(IRestartHandler.class, fRestartCommand);
session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand); session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand);
session.registerModelAdapter(IConnect.class, fConnectCommand); session.registerModelAdapter(IConnect.class, fConnectCommand);
session.registerModelAdapter(IDisconnectHandler.class, fDisconnectCommand); session.registerModelAdapter(IDisconnectHandler.class, fDisconnectCommand);
@ -238,7 +239,7 @@ public class GdbAdapterFactory
session.unregisterModelAdapter(IResumeHandler.class); session.unregisterModelAdapter(IResumeHandler.class);
session.unregisterModelAdapter(IReverseResumeHandler.class); session.unregisterModelAdapter(IReverseResumeHandler.class);
session.unregisterModelAdapter(IResumeWithoutSignalHandler.class); session.unregisterModelAdapter(IResumeWithoutSignalHandler.class);
session.unregisterModelAdapter(IRestart.class); session.unregisterModelAdapter(IRestartHandler.class);
session.unregisterModelAdapter(ITerminateHandler.class); session.unregisterModelAdapter(ITerminateHandler.class);
session.unregisterModelAdapter(IConnect.class); session.unregisterModelAdapter(IConnect.class);
session.unregisterModelAdapter(IDisconnectHandler.class); session.unregisterModelAdapter(IDisconnectHandler.class);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems and others. * Copyright (c) 2006, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,17 +7,15 @@
* *
* Contributors: * Contributors:
* Wind River Systems - initial API and implementation * Wind River Systems - initial API and implementation
* Navid Mehregani (TI) - Bug 289526 - Migrate the Restart feature to the new one, as supported by the platform
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.actions; package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.cdt.debug.core.model.IRestart;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.debug.ui.actions.DsfCommandRunnable;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend; import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
@ -26,10 +24,16 @@ import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.DebugException; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.debug.core.commands.IRestartHandler;
import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.IProcess;
public class GdbRestartCommand implements IRestart { public class GdbRestartCommand implements IRestartHandler {
private final DsfExecutor fExecutor; private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker; private final DsfServicesTracker fTracker;
private final GdbLaunch fLaunch; private final GdbLaunch fLaunch;
@ -44,84 +48,89 @@ public class GdbRestartCommand implements IRestart {
fTracker.dispose(); fTracker.dispose();
} }
// Run control may not be available after a connection is terminated and shut down. public void canExecute(final IEnabledStateRequest request) {
public boolean canRestart() { if (request.getElements().length != 1) {
Query<Boolean> canRestart = new Query<Boolean>() { request.setEnabled(false);
@Override request.done();
protected void execute(DataRequestMonitor<Boolean> rm) { return;
}
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
IGDBControl gdbControl = fTracker.getService(IGDBControl.class); IGDBControl gdbControl = fTracker.getService(IGDBControl.class);
if (gdbControl != null) { if (gdbControl != null) {
rm.setData(gdbControl.canRestart()); request.setEnabled(gdbControl.canRestart());
} else { } else {
rm.setData(false); request.setEnabled(false);
} }
request.done();
rm.done(); }
} });
};
fExecutor.execute(canRestart);
try {
return canRestart.get();
} catch (InterruptedException e1) {
} catch (ExecutionException e1) {
}
return false;
} }
private class UpdateLaunchJob extends Job {
private final AtomicReference<IPath> fExecPathRef;
UpdateLaunchJob(IPath path) {
super(""); //$NON-NLS-1$
setSystem(true);
fExecPathRef = new AtomicReference<IPath>(path);
}
@Override
protected IStatus run(IProgressMonitor monitor) {
// Now that we restarted the inferior, we must add it to our launch
// we must do this here because we cannot do it in the executor, or else
// it deadlocks
// We must first remove the old inferior from our launch (since it uses
// the same name and we use that name to find the old one)
//
// Remove
String inferiorLabel = fExecPathRef.get().lastSegment();
public void restart() throws DebugException IProcess[] launchProcesses = fLaunch.getProcesses();
{ for (IProcess p : launchProcesses) {
final AtomicReference<IPath> execPathRef = new AtomicReference<IPath>(); if (p.getLabel().equals(inferiorLabel)) {
Query<Object> restartQuery = new Query<Object>() { fLaunch.removeProcess(p);
@Override break;
protected void execute(final DataRequestMonitor<Object> rm) { }
}
// Add
try {
fLaunch.addInferiorProcess(inferiorLabel);
} catch (CoreException e) {
}
return Status.OK_STATUS;
}
}
public boolean execute(final IDebugCommandRequest request) {
if (request.getElements().length != 1) {
request.done();
return false;
}
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
final IGDBControl gdbControl = fTracker.getService(IGDBControl.class); final IGDBControl gdbControl = fTracker.getService(IGDBControl.class);
final IGDBBackend backend = fTracker.getService(IGDBBackend.class); final IGDBBackend backend = fTracker.getService(IGDBBackend.class);
if (gdbControl != null && backend != null) { if (gdbControl != null && backend != null) {
execPathRef.set(backend.getProgramPath()); gdbControl.initInferiorInputOutput(new RequestMonitor(fExecutor, null) {
gdbControl.initInferiorInputOutput(new RequestMonitor(fExecutor, rm) {
@Override @Override
protected void handleSuccess() { protected void handleCompleted() {
gdbControl.createInferiorProcess(); if (isSuccess()) {
gdbControl.restart(fLaunch, rm); gdbControl.createInferiorProcess();
gdbControl.restart(fLaunch, new RequestMonitor(fExecutor, null));
// Update the launch outside the executor
new UpdateLaunchJob(backend.getProgramPath()).schedule();
}
} }
}); });
} else {
rm.done();
} }
} }
}; });
return false;
fExecutor.execute(restartQuery); }
try {
restartQuery.get();
} catch (InterruptedException e1) {
} catch (ExecutionException e1) {
}
// Now that we restarted the inferior, we must add it to our launch
// we must do this here because we cannot do it in the executor, or else
// it deadlocks
// We must first remove the old inferior from our launch (since it uses
// the same name and we use that name to find the old one)
//
// Remove
String inferiorLabel = execPathRef.get().lastSegment();
IProcess[] launchProcesses = fLaunch.getProcesses();
for (IProcess p : launchProcesses) {
if (p.getLabel().equals(inferiorLabel)) {
fLaunch.removeProcess(p);
break;
}
}
// Add
try {
fLaunch.addInferiorProcess(inferiorLabel);
} catch (CoreException e) {
throw new DebugException(e.getStatus());
}
}
} }