1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-08 08:45:44 +02:00

[217020] Refactored ICommandControl interface to use a token to identify queued commands.

This commit is contained in:
Pawel Piech 2008-04-02 04:09:35 +00:00
parent 706d77cc0c
commit b76951e59e
12 changed files with 163 additions and 134 deletions

View file

@ -55,18 +55,20 @@ public class CommandCache implements ICommandListener
*/ */
/** List of the request monitors associated with this command */ /** List of the request monitors associated with this command */
List<DataRequestMonitor<ICommandResult>> fCurrentRequestMonitors ; private final List<DataRequestMonitor<ICommandResult>> fCurrentRequestMonitors ;
/** Original command. Need for reference from Queue completion notification */ /** Original command. Need for reference from Queue completion notification */
ICommand<ICommandResult> fCommand; private final ICommand<ICommandResult> fCommand;
/** Style of this command ( internal coalesced or not) */ /** Style of this command ( internal coalesced or not) */
CommandStyle fCmdStyle; private final CommandStyle fCmdStyle;
/** Command being processed for this command */ /** Command being processed for this command */
CommandInfo fCoalescedCmd; private CommandInfo fCoalescedCmd;
private ICommandToken fToken;
public CommandInfo( CommandStyle cmdstyle, ICommand<ICommandResult> cmd, DataRequestMonitor<ICommandResult> rm ) { public CommandInfo(CommandStyle cmdstyle, ICommand<ICommandResult> cmd, DataRequestMonitor<ICommandResult> rm ) {
fCmdStyle = cmdstyle; fCmdStyle = cmdstyle;
fCommand = cmd; fCommand = cmd;
fCurrentRequestMonitors = new LinkedList<DataRequestMonitor<ICommandResult>>(); fCurrentRequestMonitors = new LinkedList<DataRequestMonitor<ICommandResult>>();
@ -219,7 +221,7 @@ public class CommandCache implements ICommandListener
* does not continue to process it. * does not continue to process it.
*/ */
fPendingQCommandsNotYetSent.remove(currentUnsentEntry); fPendingQCommandsNotYetSent.remove(currentUnsentEntry);
fCommandControl.removeCommand(unsentCommand); fCommandControl.removeCommand(currentUnsentEntry.fToken);
return( coalescedCmdInfo ); return( coalescedCmdInfo );
} }
@ -316,7 +318,7 @@ public class CommandCache implements ICommandListener
final CommandInfo finalCachedCmd = cachedCmd; final CommandInfo finalCachedCmd = cachedCmd;
fPendingQCommandsNotYetSent.add(finalCachedCmd); fPendingQCommandsNotYetSent.add(finalCachedCmd);
fCommandControl.queueCommand( finalCachedCmd.fToken = fCommandControl.queueCommand(
finalCachedCmd.getCommand(), finalCachedCmd.getCommand(),
new DataRequestMonitor<ICommandResult>(fSession.getExecutor(), null) { new DataRequestMonitor<ICommandResult>(fSession.getExecutor(), null) {
@Override @Override
@ -476,7 +478,7 @@ public class CommandCache implements ICommandListener
fCachedContexts.clear(); fCachedContexts.clear();
} }
public void commandRemoved(ICommand<? extends ICommandResult> command) { public void commandRemoved(ICommandToken token) {
/* /*
* Do nothing. * Do nothing.
*/ */
@ -486,7 +488,7 @@ public class CommandCache implements ICommandListener
* (non-Javadoc) * (non-Javadoc)
* @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandQueued(org.eclipse.dd.dsf.mi.core.command.ICommand) * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandQueued(org.eclipse.dd.dsf.mi.core.command.ICommand)
*/ */
public void commandQueued(ICommand<? extends ICommandResult> command) { public void commandQueued(ICommandToken token) {
/* /*
* Do nothing. * Do nothing.
*/ */
@ -496,7 +498,7 @@ public class CommandCache implements ICommandListener
* (non-Javadoc) * (non-Javadoc)
* @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandDone(org.eclipse.dd.dsf.mi.core.command.ICommand, org.eclipse.dd.dsf.mi.core.command.ICommandResult) * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandDone(org.eclipse.dd.dsf.mi.core.command.ICommand, org.eclipse.dd.dsf.mi.core.command.ICommandResult)
*/ */
public void commandDone(ICommand<? extends ICommandResult> command, ICommandResult result) { public void commandDone(ICommandToken token, ICommandResult result) {
/* /*
* We handle the done with a runnable where we initiated the command * We handle the done with a runnable where we initiated the command
* so there is nothing to do here. * so there is nothing to do here.
@ -511,11 +513,11 @@ public class CommandCache implements ICommandListener
* (non-Javadoc) * (non-Javadoc)
* @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandSent(org.eclipse.dd.dsf.mi.core.command.ICommand) * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandSent(org.eclipse.dd.dsf.mi.core.command.ICommand)
*/ */
public void commandSent(ICommand<? extends ICommandResult> command) { public void commandSent(ICommandToken token) {
// Cast the generic ?'s to concrete types in the cache implementation. // Cast the generic ?'s to concrete types in the cache implementation.
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ICommand<ICommandResult> genericCommand = (ICommand<ICommandResult>)command; ICommand<ICommandResult> genericCommand = (ICommand<ICommandResult>)token.getCommand();
CommandInfo cachedCmd = new CommandInfo( CommandStyle.NONCOALESCED, genericCommand, null) ; CommandInfo cachedCmd = new CommandInfo( CommandStyle.NONCOALESCED, genericCommand, null) ;

View file

@ -17,7 +17,7 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
* and asynchronous events. * and asynchronous events.
*/ */
public interface ICommandControl { public interface ICommandControl {
/** /**
* Adds the specified command to the queue of commands to be processed. * Adds the specified command to the queue of commands to be processed.
* *
@ -25,7 +25,7 @@ public interface ICommandControl {
* @param rm Request completion monitor * @param rm Request completion monitor
* @return None * @return None
*/ */
<V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm); <V extends ICommandResult> ICommandToken queueCommand(ICommand<V> command, DataRequestMonitor<V> rm);
/** /**
* Removes the specified command from the processor queue. * Removes the specified command from the processor queue.
@ -33,17 +33,7 @@ public interface ICommandControl {
* @param command Specific command to be removed * @param command Specific command to be removed
* @return None * @return None
*/ */
void removeCommand(ICommand<? extends ICommandResult> command); void removeCommand(ICommandToken token);
/**
* Attempts to cancel and already sent command. Some versions
* of GDB/MI implement control commands which allow this. The
* GDB/MI standard does not currently allow for this.
*
* @param command Specific command to be removed
* @return None
*/
void cancelCommand(ICommand<? extends ICommandResult> command);
/** /**
* Adds a notification handler for the Command processor. * Adds a notification handler for the Command processor.

View file

@ -18,7 +18,7 @@ public interface ICommandListener {
* @return None * @return None
* @param command Command which has been added to the Queue * @param command Command which has been added to the Queue
*/ */
public void commandQueued(ICommand<? extends ICommandResult> command); public void commandQueued(ICommandToken token);
/** /**
* Notification that the given command was sent to the debugger. At this * Notification that the given command was sent to the debugger. At this
@ -29,7 +29,7 @@ public interface ICommandListener {
* @return None * @return None
* @param command * @param command
*/ */
public void commandSent(ICommand<? extends ICommandResult> command); public void commandSent(ICommandToken token);
/** /**
* Notifies that the specified command has been removed from the * Notifies that the specified command has been removed from the
@ -42,7 +42,7 @@ public interface ICommandListener {
* @return None * @return None
* @param Command which has been sent to the backend * @param Command which has been sent to the backend
*/ */
public void commandRemoved(ICommand<? extends ICommandResult> command); public void commandRemoved(ICommandToken token);
/** /**
* Notifies that the specified command has been completed. * Notifies that the specified command has been completed.
@ -50,5 +50,5 @@ public interface ICommandListener {
* @return None * @return None
* @param Command which has been sent to the backend * @param Command which has been sent to the backend
*/ */
public void commandDone(ICommand<? extends ICommandResult> command, ICommandResult result); public void commandDone(ICommandToken token, ICommandResult result);
} }

View file

@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.service.command;
/**
* Token returned by ICommandControl.queueCommand(). This token can be used
* to uniquely identify a command when calling ICommandControl.removeCommand()
* or when implementing the ICommandListener listener methods.
*/
public interface ICommandToken {
/**
* Returns the command that this was created for.
*/
public ICommand<? extends ICommandResult> getCommand();
}

View file

@ -27,6 +27,7 @@ import org.eclipse.dd.dsf.debug.service.command.ICommand;
import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
import org.eclipse.dd.dsf.debug.service.command.ICommandToken;
import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.debug.service.command.IEventListener;
import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.AbstractDsfService;
import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.DsfSession;
@ -44,10 +45,12 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon
// Structure used to store command information in services internal queues. // Structure used to store command information in services internal queues.
private static class CommandHandle { private static class CommandHandle {
final private ICommandToken fToken;
final private AbstractPDACommand<PDACommandResult> fCommand; final private AbstractPDACommand<PDACommandResult> fCommand;
final private DataRequestMonitor<PDACommandResult> fRequestMonitor; final private DataRequestMonitor<PDACommandResult> fRequestMonitor;
CommandHandle(AbstractPDACommand<PDACommandResult> c, DataRequestMonitor<PDACommandResult> rm) { CommandHandle(ICommandToken token, AbstractPDACommand<PDACommandResult> c, DataRequestMonitor<PDACommandResult> rm) {
fToken = token;
fCommand = c; fCommand = c;
fRequestMonitor = rm; fRequestMonitor = rm;
} }
@ -334,7 +337,13 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon
} }
public <V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm) { public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, DataRequestMonitor<V> rm) {
ICommandToken token = new ICommandToken() {
public ICommand<?> getCommand() {
return command;
}
};
if (command instanceof AbstractPDACommand<?>) { if (command instanceof AbstractPDACommand<?>) {
// Cast from command with "<V extends ICommandResult>" to a more concrete // Cast from command with "<V extends ICommandResult>" to a more concrete
// type to use internally in the command control. // type to use internally in the command control.
@ -346,9 +355,9 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon
DataRequestMonitor<PDACommandResult> pdaRM = (DataRequestMonitor<PDACommandResult>)rm; DataRequestMonitor<PDACommandResult> pdaRM = (DataRequestMonitor<PDACommandResult>)rm;
// Add the command to the queue and notify command listeners. // Add the command to the queue and notify command listeners.
fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) ); fCommandQueue.add( new CommandHandle(token, pdaCommand, pdaRM) );
for (ICommandListener listener : fCommandListeners) { for (ICommandListener listener : fCommandListeners) {
listener.commandQueued(command); listener.commandQueued(token);
} }
// In a separate dispatch cycle. This allows command listeners to respond to the // In a separate dispatch cycle. This allows command listeners to respond to the
@ -358,25 +367,20 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon
processQueues(); processQueues();
} }
}); });
} else { } else {
PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command); PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command);
} }
return token;
} }
public void cancelCommand(ICommand<? extends ICommandResult> command) { public void removeCommand(ICommandToken token) {
// This debugger is unable of canceling commands once they have
// been sent.
}
public void removeCommand(ICommand<? extends ICommandResult> command) {
// Removes given command from the queue and notify the listeners // Removes given command from the queue and notify the listeners
for (Iterator<CommandHandle> itr = fCommandQueue.iterator(); itr.hasNext();) { for (Iterator<CommandHandle> itr = fCommandQueue.iterator(); itr.hasNext();) {
CommandHandle handle = itr.next(); CommandHandle handle = itr.next();
if (command.equals(handle.fCommand)) { if (token.equals(handle.fToken)) {
itr.remove(); itr.remove();
for (ICommandListener listener : fCommandListeners) { for (ICommandListener listener : fCommandListeners) {
listener.commandRemoved(command); listener.commandRemoved(token);
} }
} }
} }
@ -414,7 +418,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon
// Notify listeners of the response // Notify listeners of the response
for (ICommandListener listener : fCommandListeners) { for (ICommandListener listener : fCommandListeners) {
listener.commandDone(handle.fCommand, result); listener.commandDone(handle.fToken, result);
} }
// Process next command in queue. // Process next command in queue.
@ -431,7 +435,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon
// Notify listeners also. // Notify listeners also.
for (ICommandListener listener : fCommandListeners) { for (ICommandListener listener : fCommandListeners) {
listener.commandDone(handle.fCommand, null); listener.commandDone(handle.fToken, null);
} }
} }
@ -462,7 +466,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon
fTxCommands.add(handle); fTxCommands.add(handle);
PDAPlugin.debug("C: " + handle.fCommand.getRequest()); PDAPlugin.debug("C: " + handle.fCommand.getRequest());
for (ICommandListener listener : fCommandListeners) { for (ICommandListener listener : fCommandListeners) {
listener.commandSent(handle.fCommand); listener.commandSent(handle.fToken);
} }
} }
} }

View file

@ -23,6 +23,7 @@ import org.eclipse.dd.dsf.concurrent.Query;
import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommand;
import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
import org.eclipse.dd.dsf.debug.service.command.ICommandToken;
import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -53,17 +54,17 @@ public class BasicTests extends CommandControlTestsBase {
List<CommandInfo> fRemovedCommands = new LinkedList<CommandInfo>(); List<CommandInfo> fRemovedCommands = new LinkedList<CommandInfo>();
List<CommandInfo> fSentCommands = new LinkedList<CommandInfo>(); List<CommandInfo> fSentCommands = new LinkedList<CommandInfo>();
public void commandDone(ICommand<? extends ICommandResult> command, ICommandResult result) { public void commandDone(ICommandToken token, ICommandResult result) {
fDoneCommands.add(new CommandInfo(command, result)); fDoneCommands.add(new CommandInfo(token.getCommand(), result));
} }
public void commandQueued(ICommand<? extends ICommandResult> command) { public void commandQueued(ICommandToken token) {
fQueuedCommands.add(new CommandInfo(command, null)); fQueuedCommands.add(new CommandInfo(token.getCommand(), null));
} }
public void commandRemoved(ICommand<? extends ICommandResult> command) { public void commandRemoved(ICommandToken token) {
fRemovedCommands.add(new CommandInfo(command, null)); fRemovedCommands.add(new CommandInfo(token.getCommand(), null));
} }
public void commandSent(ICommand<? extends ICommandResult> command) { public void commandSent(ICommandToken token) {
fSentCommands.add(new CommandInfo(command, null)); fSentCommands.add(new CommandInfo(token.getCommand(), null));
} }
void reset() { void reset() {
@ -106,7 +107,7 @@ public class BasicTests extends CommandControlTestsBase {
Query<Object> queueRemoveCommandQuery = new Query<Object>() { Query<Object> queueRemoveCommandQuery = new Query<Object>() {
@Override @Override
protected void execute(DataRequestMonitor<Object> rm) { protected void execute(DataRequestMonitor<Object> rm) {
fCommandControl.queueCommand( ICommandToken token = fCommandControl.queueCommand(
testCommand, testCommand,
new DataRequestMonitor<PDACommandResult>(fExecutor, null) { new DataRequestMonitor<PDACommandResult>(fExecutor, null) {
@Override @Override
@ -114,7 +115,7 @@ public class BasicTests extends CommandControlTestsBase {
Assert.fail("This command should never have been executed."); Assert.fail("This command should never have been executed.");
} }
}); });
fCommandControl.removeCommand(testCommand); fCommandControl.removeCommand(token);
rm.setData(new Object()); rm.setData(new Object());
rm.done(); rm.done();

View file

@ -40,6 +40,7 @@ import org.eclipse.dd.dsf.debug.service.command.ICommand;
import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
import org.eclipse.dd.dsf.debug.service.command.ICommandToken;
import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.debug.service.command.IEventListener;
import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfServicesTracker;
@ -1487,13 +1488,19 @@ public class MIVariableManager implements ICommandControl {
}); });
} }
public <V extends ICommandResult> void queueCommand(final ICommand<V> command, DataRequestMonitor<V> rm) { public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, DataRequestMonitor<V> rm) {
final ICommandToken token = new ICommandToken() {
public ICommand<? extends ICommandResult> getCommand() {
return command;
}
};
// The MIVariableManager does not buffer commands itself, but sends them directly to the real // The MIVariableManager does not buffer commands itself, but sends them directly to the real
// MICommandControl service. Therefore, we must immediately tell our calling cache that the command // MICommandControl service. Therefore, we must immediately tell our calling cache that the command
// has been sent, since we can never cancel it. Note that this removes any option of coalescing, // has been sent, since we can never cancel it. Note that this removes any option of coalescing,
// but coalescing was not applicable to variableObjects anyway. // but coalescing was not applicable to variableObjects anyway.
processCommandSent(command); processCommandSent(token);
if (command instanceof ExprMetaGetVar) { if (command instanceof ExprMetaGetVar) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -1512,6 +1519,7 @@ public class MIVariableManager implements ICommandControl {
getData().getType(), getData().getType(),
!getData().isComplex())); !getData().isComplex()));
drm.done(); drm.done();
processCommandDone(token, drm.getData());
} }
}); });
} else if (command instanceof ExprMetaGetAttributes) { } else if (command instanceof ExprMetaGetAttributes) {
@ -1530,6 +1538,7 @@ public class MIVariableManager implements ICommandControl {
protected void handleSuccess() { protected void handleSuccess() {
drm.setData(new ExprMetaGetAttributesInfo(getData())); drm.setData(new ExprMetaGetAttributesInfo(getData()));
drm.done(); drm.done();
processCommandDone(token, drm.getData());
} }
}); });
} }
@ -1555,6 +1564,7 @@ public class MIVariableManager implements ICommandControl {
drm.setData( drm.setData(
new ExprMetaGetValueInfo(getData().getFormattedValue())); new ExprMetaGetValueInfo(getData().getFormattedValue()));
drm.done(); drm.done();
processCommandDone(token, drm.getData());
} }
}); });
} }
@ -1577,6 +1587,7 @@ public class MIVariableManager implements ICommandControl {
protected void handleSuccess() { protected void handleSuccess() {
drm.setData(new ExprMetaGetChildrenInfo(getData())); drm.setData(new ExprMetaGetChildrenInfo(getData()));
drm.done(); drm.done();
processCommandDone(token, drm.getData());
} }
}); });
} }
@ -1598,6 +1609,7 @@ public class MIVariableManager implements ICommandControl {
protected void handleSuccess() { protected void handleSuccess() {
drm.setData(new ExprMetaGetChildCountInfo(getData())); drm.setData(new ExprMetaGetChildCountInfo(getData()));
drm.done(); drm.done();
processCommandDone(token, drm.getData());
} }
}); });
} }
@ -1610,7 +1622,8 @@ public class MIVariableManager implements ICommandControl {
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
"Unexpected Expression Meta command", null)); //$NON-NLS-1$ "Unexpected Expression Meta command", null)); //$NON-NLS-1$
rm.done(); rm.done();
} }
return token;
} }
/* /*
@ -1621,7 +1634,7 @@ public class MIVariableManager implements ICommandControl {
* (non-Javadoc) * (non-Javadoc)
* @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand)
*/ */
public void removeCommand(ICommand<? extends ICommandResult> command) { public void removeCommand(ICommandToken token) {
// It is impossible to remove a command from the MIVariableManager. // It is impossible to remove a command from the MIVariableManager.
// This should never be called, if we did things right. // This should never be called, if we did things right.
assert false; assert false;
@ -1637,19 +1650,24 @@ public class MIVariableManager implements ICommandControl {
* (non-Javadoc) * (non-Javadoc)
* @see org.eclipse.dd.mi.service.command.IDebuggerControl#cancelCommand(org.eclipse.dd.mi.service.command.commands.ICommand) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#cancelCommand(org.eclipse.dd.mi.service.command.commands.ICommand)
*/ */
public void cancelCommand(ICommand<? extends ICommandResult> command) {}
public void addCommandListener(ICommandListener processor) { fCommandProcessors.add(processor); } public void addCommandListener(ICommandListener processor) { fCommandProcessors.add(processor); }
public void removeCommandListener(ICommandListener processor) { fCommandProcessors.remove(processor); } public void removeCommandListener(ICommandListener processor) { fCommandProcessors.remove(processor); }
public void addEventListener(IEventListener processor) {} public void addEventListener(IEventListener processor) {}
public void removeEventListener(IEventListener processor) {} public void removeEventListener(IEventListener processor) {}
private void processCommandSent(ICommand<?> command) { private void processCommandSent(ICommandToken token) {
for (ICommandListener processor : fCommandProcessors) { for (ICommandListener processor : fCommandProcessors) {
processor.commandSent(command); processor.commandSent(token);
} }
} }
private void processCommandDone(ICommandToken token, ICommandResult result) {
for (ICommandListener processor : fCommandProcessors) {
processor.commandDone(token, result);
}
}
private void markAllOutOfDate() { private void markAllOutOfDate() {
MIRootVariableObject root; MIRootVariableObject root;
while ((root = updatedRootList.poll()) != null) { while ((root = updatedRootList.poll()) != null) {
@ -1679,5 +1697,4 @@ public class MIVariableManager implements ICommandControl {
// The views will fully refresh on a MemoryChangedEvent // The views will fully refresh on a MemoryChangedEvent
markAllOutOfDate(); markAllOutOfDate();
} }
} }

View file

@ -30,6 +30,7 @@ import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommand;
import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
import org.eclipse.dd.dsf.debug.service.command.ICommandToken;
import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.debug.service.command.IEventListener;
import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.internal.MIPlugin;
@ -204,11 +205,12 @@ public abstract class AbstractCLIProcess extends Process
} }
} }
public void commandQueued(ICommand<? extends ICommandResult> command) { public void commandQueued(ICommandToken token) {
// Ignore // Ignore
} }
public void commandSent(ICommand<? extends ICommandResult> command) { public void commandSent(ICommandToken token) {
ICommand<?> command = token.getCommand();
// Check if the command is a CLI command and if it did not originate from this class. // Check if the command is a CLI command and if it did not originate from this class.
if (command instanceof CLICommand<?> && if (command instanceof CLICommand<?> &&
!(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole)) !(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole))
@ -217,12 +219,13 @@ public abstract class AbstractCLIProcess extends Process
} }
} }
public void commandRemoved(ICommand<? extends ICommandResult> command) { public void commandRemoved(ICommandToken token) {
// Ignore // Ignore
} }
public void commandDone(ICommand<? extends ICommandResult> command, ICommandResult result) { public void commandDone(ICommandToken token, ICommandResult result) {
if (command instanceof CLICommand<?> && ICommand<?> command = token.getCommand();
if (token.getCommand() instanceof CLICommand<?> &&
!(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole)) !(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole))
{ {
fSuppressConsoleOutputCounter--; fSuppressConsoleOutputCounter--;

View file

@ -36,6 +36,7 @@ import org.eclipse.dd.dsf.debug.service.command.ICommand;
import org.eclipse.dd.dsf.debug.service.command.ICommandControl; import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
import org.eclipse.dd.dsf.debug.service.command.ICommandToken;
import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.debug.service.command.IEventListener;
import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.AbstractDsfService;
import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.DsfSession;
@ -182,15 +183,8 @@ public abstract class AbstractMIControl extends AbstractDsfService
* @see org.eclipse.dd.dsf.debug.service.command.ICommandControl#addCommand(org.eclipse.dd.dsf.debug.service.command.ICommand, org.eclipse.dd.dsf.concurrent.RequestMonitor) * @see org.eclipse.dd.dsf.debug.service.command.ICommandControl#addCommand(org.eclipse.dd.dsf.debug.service.command.ICommand, org.eclipse.dd.dsf.concurrent.RequestMonitor)
*/ */
public <V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm) { public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, DataRequestMonitor<V> rm) {
// If the command control stopped processing commands, just return an error immediately.
if (fStoppedCommandProcessing) {
rm.setStatus(genStatus("Connection is shut down")); //$NON-NLS-1$
rm.done();
return;
}
// Cast the command to MI Command type. This will cause a cast exception to be // Cast the command to MI Command type. This will cause a cast exception to be
// thrown if the client did not give an MI command as an argument. // thrown if the client did not give an MI command as an argument.
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -202,8 +196,12 @@ public abstract class AbstractMIControl extends AbstractDsfService
DataRequestMonitor<MIInfo> miDone = (DataRequestMonitor<MIInfo>)rm; DataRequestMonitor<MIInfo> miDone = (DataRequestMonitor<MIInfo>)rm;
final CommandHandle handle = new CommandHandle(miCommand, miDone); final CommandHandle handle = new CommandHandle(miCommand, miDone);
if ( fRxCommands.size() > 3 ) { // If the command control stopped processing commands, just return an error immediately.
if (fStoppedCommandProcessing) {
rm.setStatus(genStatus("Connection is shut down")); //$NON-NLS-1$
rm.done();
} else if ( fRxCommands.size() > 3 ) {
/* /*
* We only allow three outstanding commands to be on the wire to the backend * We only allow three outstanding commands to be on the wire to the backend
@ -238,7 +236,7 @@ public abstract class AbstractMIControl extends AbstractDsfService
CommandHandle cmdHandle = new CommandHandle( CommandHandle cmdHandle = new CommandHandle(
new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null); new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null);
fTxCommands.add(cmdHandle); fTxCommands.add(cmdHandle);
MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getToken() + cmdHandle.getCommand()); //$NON-NLS-1$ MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getTokenId() + cmdHandle.getCommand()); //$NON-NLS-1$
} }
// Before the command is sent, Check the Stack level and send it to // Before the command is sent, Check the Stack level and send it to
@ -251,12 +249,13 @@ public abstract class AbstractMIControl extends AbstractDsfService
CommandHandle cmdHandle = new CommandHandle( CommandHandle cmdHandle = new CommandHandle(
new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null); new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null);
fTxCommands.add(cmdHandle); fTxCommands.add(cmdHandle);
MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getToken() + cmdHandle.getCommand()); //$NON-NLS-1$ MIPlugin.debug(MIPlugin.getDebugTime() + " " + cmdHandle.getTokenId() + cmdHandle.getCommand()); //$NON-NLS-1$
} }
fTxCommands.add(handle); fTxCommands.add(handle);
} }
} }
return handle;
} }
/* /*
@ -267,12 +266,12 @@ public abstract class AbstractMIControl extends AbstractDsfService
* (non-Javadoc) * (non-Javadoc)
* @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand)
*/ */
public void removeCommand(ICommand<? extends ICommandResult> command) { public void removeCommand(ICommandToken token) {
synchronized(fCommandQueue) { synchronized(fCommandQueue) {
for ( CommandHandle handle : fCommandQueue ) { for ( CommandHandle handle : fCommandQueue ) {
if ( handle.getCommand().equals(command)) { if ( handle.equals(token)) {
fCommandQueue.remove(handle); fCommandQueue.remove(handle);
final CommandHandle finalHandle = handle; final CommandHandle finalHandle = handle;
@ -287,18 +286,6 @@ public abstract class AbstractMIControl extends AbstractDsfService
} }
} }
/*
* This command allows the user to try and cancel commands which have been handed off to the
* backend. Some backends support this with extended GDB/MI commands. If the support is there
* then we will attempt it. Because of the bidirectional nature of the GDB/MI command stream
* there is no guarantee that this will work. The response to the command could be on its way
* back when the cancel command is being issued.
*
* (non-Javadoc)
* @see org.eclipse.dd.mi.service.command.IDebuggerControl#cancelCommand(org.eclipse.dd.mi.service.command.commands.ICommand)
*/
public void cancelCommand(ICommand<? extends ICommandResult> command) {}
/* /*
* Allows a user ( typically a cache manager ) to sign up a listener to monitor command queue * Allows a user ( typically a cache manager ) to sign up a listener to monitor command queue
* activity. * activity.
@ -339,19 +326,19 @@ public abstract class AbstractMIControl extends AbstractDsfService
private void processCommandQueued(CommandHandle commandHandle) { private void processCommandQueued(CommandHandle commandHandle) {
for (ICommandListener processor : fCommandProcessors) { for (ICommandListener processor : fCommandProcessors) {
processor.commandQueued(commandHandle.getCommand()); processor.commandQueued(commandHandle);
} }
} }
private void processCommandRemoved(CommandHandle commandHandle) { private void processCommandRemoved(CommandHandle commandHandle) {
for (ICommandListener processor : fCommandProcessors) { for (ICommandListener processor : fCommandProcessors) {
processor.commandRemoved(commandHandle.getCommand()); processor.commandRemoved(commandHandle);
} }
} }
private void processCommandSent(CommandHandle commandHandle) { private void processCommandSent(CommandHandle commandHandle) {
MIPlugin.debug(MIPlugin.getDebugTime() + " " + commandHandle.getToken() + commandHandle.getCommand()); //$NON-NLS-1$ MIPlugin.debug(MIPlugin.getDebugTime() + " " + commandHandle.getTokenId() + commandHandle.getCommand()); //$NON-NLS-1$
for (ICommandListener processor : fCommandProcessors) { for (ICommandListener processor : fCommandProcessors) {
processor.commandSent(commandHandle.getCommand()); processor.commandSent(commandHandle);
} }
} }
@ -374,7 +361,7 @@ public abstract class AbstractMIControl extends AbstractDsfService
* Tell the listeners we have completed this one. * Tell the listeners we have completed this one.
*/ */
for (ICommandListener processor : fCommandProcessors) { for (ICommandListener processor : fCommandProcessors) {
processor.commandDone(commandHandle == null ? null : commandHandle.getCommand(), result); processor.commandDone(commandHandle, result);
} }
} }
@ -389,14 +376,13 @@ public abstract class AbstractMIControl extends AbstractDsfService
* A global counter for all command, the token will be use to identify uniquely a command. * A global counter for all command, the token will be use to identify uniquely a command.
* Unless the value wraps around which is unlikely. * Unless the value wraps around which is unlikely.
*/ */
private int fTokenIdCounter = 0 ;
private static int globalCounter = 0 ; private int getNewTokenId() {
int count = ++fTokenIdCounter;
private static synchronized int getUniqToken() {
int count = ++globalCounter;
// If we ever wrap around. // If we ever wrap around.
if (count <= 0) { if (count <= 0) {
count = globalCounter = 1; count = fTokenIdCounter = 1;
} }
return count; return count;
} }
@ -406,8 +392,8 @@ public abstract class AbstractMIControl extends AbstractDsfService
* individual request. * individual request.
*/ */
public static class CommandHandle { private class CommandHandle implements ICommandToken {
private MICommand<MIInfo> fCommand; private MICommand<MIInfo> fCommand;
private DataRequestMonitor<MIInfo> fRequestMonitor; private DataRequestMonitor<MIInfo> fRequestMonitor;
private int fTokenId ; private int fTokenId ;
@ -415,12 +401,13 @@ public abstract class AbstractMIControl extends AbstractDsfService
CommandHandle(MICommand<MIInfo> c, DataRequestMonitor<MIInfo> d) { CommandHandle(MICommand<MIInfo> c, DataRequestMonitor<MIInfo> d) {
fCommand = c; fCommand = c;
fRequestMonitor = d; fRequestMonitor = d;
fTokenId = getUniqToken() ; fTokenId = getNewTokenId() ;
} }
public MICommand<MIInfo> getCommand() { return fCommand; } public MICommand<MIInfo> getCommand() { return fCommand; }
public DataRequestMonitor<MIInfo> getRequestMonitor() { return fRequestMonitor; } public DataRequestMonitor<MIInfo> getRequestMonitor() { return fRequestMonitor; }
public Integer getToken() { return fTokenId; } public Integer getTokenId() { return fTokenId; }
//public String getThreadId() { return null; } //public String getThreadId() { return null; }
public Integer getStackFrameId() { public Integer getStackFrameId() {
IFrameDMContext frameCtx = DMContexts.getAncestorOfType(fCommand.getContext(), IFrameDMContext.class); IFrameDMContext frameCtx = DMContexts.getAncestorOfType(fCommand.getContext(), IFrameDMContext.class);
@ -477,14 +464,14 @@ public abstract class AbstractMIControl extends AbstractDsfService
/* /*
* We note that this is an outstanding request at this point. * We note that this is an outstanding request at this point.
*/ */
fRxCommands.put(commandHandle.getToken(), commandHandle); fRxCommands.put(commandHandle.getTokenId(), commandHandle);
} }
/* /*
* Construct the new command and push this command out the pipeline. * Construct the new command and push this command out the pipeline.
*/ */
String str = commandHandle.getToken() + commandHandle.getCommand().constructCommand(); String str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand();
try { try {
if (fOutputStream != null) { if (fOutputStream != null) {

View file

@ -24,9 +24,9 @@ import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.dd.dsf.debug.service.ISignals.ISignalsDMContext; import org.eclipse.dd.dsf.debug.service.ISignals.ISignalsDMContext;
import org.eclipse.dd.dsf.debug.service.command.ICommand;
import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
import org.eclipse.dd.dsf.debug.service.command.ICommandToken;
import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.debug.service.command.IEventListener;
import org.eclipse.dd.mi.service.command.commands.CLICommand; import org.eclipse.dd.mi.service.command.commands.CLICommand;
import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole; import org.eclipse.dd.mi.service.command.commands.MIInterpreterExecConsole;
@ -73,30 +73,30 @@ public class CLIEventProcessor
fCommandControl.removeEventListener(this); fCommandControl.removeEventListener(this);
} }
public void commandSent(ICommand<? extends ICommandResult> command) { public void commandSent(ICommandToken token) {
if (command instanceof CLICommand<?>) { if (token.getCommand() instanceof CLICommand<?>) {
processStateChanges( (CLICommand<?>)command ); processStateChanges( (CLICommand<?>)token.getCommand() );
} }
else if (command instanceof MIInterpreterExecConsole<?>) { else if (token.getCommand() instanceof MIInterpreterExecConsole<?>) {
processStateChanges( (MIInterpreterExecConsole<?>)command ); processStateChanges( (MIInterpreterExecConsole<?>)token.getCommand() );
} }
} }
public void commandDone(ICommand<? extends ICommandResult> command, ICommandResult result) { public void commandDone(ICommandToken token, ICommandResult result) {
if (command instanceof CLICommand<?>) { if (token.getCommand() instanceof CLICommand<?>) {
processSettingChanges( (CLICommand<?>)command ); processSettingChanges( (CLICommand<?>)token.getCommand() );
} }
else if (command instanceof MIInterpreterExecConsole<?>) { else if (token.getCommand() instanceof MIInterpreterExecConsole<?>) {
processSettingChanges( (MIInterpreterExecConsole<?>)command ); processSettingChanges( (MIInterpreterExecConsole<?>)token.getCommand() );
} }
fEventList.clear(); fEventList.clear();
} }
public void commandQueued(ICommand<? extends ICommandResult> command) { public void commandQueued(ICommandToken token) {
// No action // No action
} }
public void commandRemoved(ICommand<? extends ICommandResult> command) { public void commandRemoved(ICommandToken token) {
// No action // No action
} }

View file

@ -32,9 +32,9 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.dsf.concurrent.Query;
import org.eclipse.dd.dsf.debug.service.command.ICommand;
import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
import org.eclipse.dd.dsf.debug.service.command.ICommandToken;
import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.debug.service.command.IEventListener;
import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.internal.MIPlugin;
@ -387,22 +387,22 @@ public class MIInferiorProcess extends Process
} }
} }
public void commandQueued(ICommand<? extends ICommandResult> command) { public void commandQueued(ICommandToken token) {
// No action // No action
} }
public void commandSent(ICommand<? extends ICommandResult> command) { public void commandSent(ICommandToken token) {
if (command instanceof CLICommand<?>) { if (token.getCommand() instanceof CLICommand<?>) {
fSuppressTargetOutputCounter++; fSuppressTargetOutputCounter++;
} }
} }
public void commandRemoved(ICommand<? extends ICommandResult> command) { public void commandRemoved(ICommandToken token) {
// No action // No action
} }
public void commandDone(ICommand<? extends ICommandResult> command, ICommandResult result) { public void commandDone(ICommandToken token, ICommandResult result) {
if (command instanceof CLICommand<?>) { if (token.getCommand() instanceof CLICommand<?>) {
fSuppressTargetOutputCounter--; fSuppressTargetOutputCounter--;
} }

View file

@ -18,6 +18,7 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommand;
import org.eclipse.dd.dsf.debug.service.command.ICommandListener; import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
import org.eclipse.dd.dsf.debug.service.command.ICommandResult; import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
import org.eclipse.dd.dsf.debug.service.command.ICommandToken;
import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.debug.service.command.IEventListener;
import org.eclipse.dd.dsf.service.DsfServicesTracker; import org.eclipse.dd.dsf.service.DsfServicesTracker;
import org.eclipse.dd.mi.internal.MIPlugin; import org.eclipse.dd.mi.internal.MIPlugin;
@ -177,19 +178,20 @@ public class MIRunControlEventProcessor
return event; return event;
} }
public void commandQueued(ICommand<?> command) { public void commandQueued(ICommandToken token) {
// Do nothing. // Do nothing.
} }
public void commandSent(ICommand<?> command) { public void commandSent(ICommandToken token) {
// Do nothing. // Do nothing.
} }
public void commandRemoved(ICommand<?> command) { public void commandRemoved(ICommandToken token) {
// Do nothing. // Do nothing.
} }
public void commandDone(ICommand<?> cmd, ICommandResult result) { public void commandDone(ICommandToken token, ICommandResult result) {
ICommand<?> cmd = token.getCommand();
MIInfo cmdResult = (MIInfo) result ; MIInfo cmdResult = (MIInfo) result ;
MIOutput output = cmdResult.getMIOutput(); MIOutput output = cmdResult.getMIOutput();
MIResultRecord rr = output.getMIResultRecord(); MIResultRecord rr = output.getMIResultRecord();