1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* 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;
@ -15,6 +16,8 @@ import org.eclipse.debug.core.DebugException;
/**
* 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
{

View file

@ -372,12 +372,14 @@
</propertyTester>
</extension>
<extension
<!-- Bug 289526 [debug view] Migrate the Restart feature to the new one, as supported by the platform
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">
<viewerContribution
targetID="org.eclipse.debug.ui.DebugView"
id="org.eclipse.cdt.debug.ui.debugview.popupMenu">
id="org.eclipse.cdt.debug.ui.debugview.popupMenu2">
<action
label="%RestartAction.label"
icon="icons/elcl16/restart.gif"
@ -387,7 +389,20 @@
enablesFor="1"
id="org.eclipse.cdt.debug.internal.ui.actions.RestartActionDelegate">
<selection class="org.eclipse.cdt.debug.core.model.IRestart"/>
</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
state="false"
style="toggle"
@ -877,18 +892,6 @@
<viewContribution
targetID="org.eclipse.debug.ui.DebugView"
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
state="false"
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
* 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:
* 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;
import org.eclipse.cdt.debug.core.model.IRestart;
import org.eclipse.core.runtime.IAdaptable;
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.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.
*/
public class RestartActionDelegate extends AbstractListenerActionDelegate {
private RestartCommandAction fRestartCommandAction;
@Override
public void init(IAction action) {
setAction(action);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.actions.AbstractDebugActionDelegate#doAction(java.lang.Object)
*/
protected void doAction( Object element ) throws DebugException {
IRestart restartTarget = getRestartTarget( element );
if ( restartTarget != null ) {
restartTarget.restart();
IRestartHandler asynchronousRestartHandler = getAsynchronousRestartHandler( element );
if (asynchronousRestartHandler!=null && fRestartCommandAction!=null ) {
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)
* @see org.eclipse.cdt.debug.internal.ui.actions.AbstractDebugActionDelegate#isEnabledFor(java.lang.Object)
*/
protected boolean isEnabledFor( Object element ) {
IRestart restartTarget = getRestartTarget( element );
if ( restartTarget != null ) {
return checkCapability( restartTarget );
IRestartHandler asynchronousRestartHandler = getAsynchronousRestartHandler( element );
if (asynchronousRestartHandler!=null && fRestartCommandAction!=null) {
return fRestartCommandAction.isEnabled();
} else {
IRestart restartTarget = getRestartTarget( element );
if ( restartTarget != null ) {
return checkCapability( restartTarget );
}
}
return false;
}
@ -79,6 +120,13 @@ public class RestartActionDelegate extends AbstractListenerActionDelegate {
return (IRestart)((IAdaptable)element).getAdapter( IRestart.class );
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 ) {
if ( element instanceof IDebugElement ) {

View file

@ -7,6 +7,7 @@
*
* Contributors:
* 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;
@ -16,7 +17,6 @@ import java.util.Map;
import java.util.WeakHashMap;
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.IReverseResumeHandler;
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.ILaunchesListener2;
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.IStepIntoHandler;
import org.eclipse.debug.core.commands.IStepOverHandler;
@ -181,7 +182,7 @@ public class GdbAdapterFactory
session.registerModelAdapter(IResumeHandler.class, fResumeCommand);
session.registerModelAdapter(IReverseResumeHandler.class, fReverseResumeCommand);
session.registerModelAdapter(IResumeWithoutSignalHandler.class, fResumeWithoutSignalCommand);
session.registerModelAdapter(IRestart.class, fRestartCommand);
session.registerModelAdapter(IRestartHandler.class, fRestartCommand);
session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand);
session.registerModelAdapter(IConnect.class, fConnectCommand);
session.registerModelAdapter(IDisconnectHandler.class, fDisconnectCommand);
@ -238,7 +239,7 @@ public class GdbAdapterFactory
session.unregisterModelAdapter(IResumeHandler.class);
session.unregisterModelAdapter(IReverseResumeHandler.class);
session.unregisterModelAdapter(IResumeWithoutSignalHandler.class);
session.unregisterModelAdapter(IRestart.class);
session.unregisterModelAdapter(IRestartHandler.class);
session.unregisterModelAdapter(ITerminateHandler.class);
session.unregisterModelAdapter(IConnect.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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,17 +7,15 @@
*
* Contributors:
* 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;
import java.util.concurrent.ExecutionException;
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.Query;
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.launching.GdbLaunch;
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.core.runtime.CoreException;
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;
public class GdbRestartCommand implements IRestart {
public class GdbRestartCommand implements IRestartHandler {
private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker;
private final GdbLaunch fLaunch;
@ -44,84 +48,89 @@ public class GdbRestartCommand implements IRestart {
fTracker.dispose();
}
// Run control may not be available after a connection is terminated and shut down.
public boolean canRestart() {
Query<Boolean> canRestart = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
public void canExecute(final IEnabledStateRequest request) {
if (request.getElements().length != 1) {
request.setEnabled(false);
request.done();
return;
}
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
IGDBControl gdbControl = fTracker.getService(IGDBControl.class);
if (gdbControl != null) {
rm.setData(gdbControl.canRestart());
request.setEnabled(gdbControl.canRestart());
} else {
rm.setData(false);
}
rm.done();
}
};
fExecutor.execute(canRestart);
try {
return canRestart.get();
} catch (InterruptedException e1) {
} catch (ExecutionException e1) {
}
return false;
request.setEnabled(false);
}
request.done();
}
});
}
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
{
final AtomicReference<IPath> execPathRef = new AtomicReference<IPath>();
Query<Object> restartQuery = new Query<Object>() {
@Override
protected void execute(final DataRequestMonitor<Object> rm) {
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) {
}
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 IGDBBackend backend = fTracker.getService(IGDBBackend.class);
if (gdbControl != null && backend != null) {
execPathRef.set(backend.getProgramPath());
gdbControl.initInferiorInputOutput(new RequestMonitor(fExecutor, rm) {
if (gdbControl != null && backend != null) {
gdbControl.initInferiorInputOutput(new RequestMonitor(fExecutor, null) {
@Override
protected void handleSuccess() {
gdbControl.createInferiorProcess();
gdbControl.restart(fLaunch, rm);
protected void handleCompleted() {
if (isSuccess()) {
gdbControl.createInferiorProcess();
gdbControl.restart(fLaunch, new RequestMonitor(fExecutor, null));
// Update the launch outside the executor
new UpdateLaunchJob(backend.getProgramPath()).schedule();
}
}
});
} else {
rm.done();
}
}
};
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());
}
}
}
});
return false;
}
}