diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java index 881493eb269..f1842403f97 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java @@ -55,18 +55,20 @@ public class CommandCache implements ICommandListener */ /** List of the request monitors associated with this command */ - List> fCurrentRequestMonitors ; + private final List> fCurrentRequestMonitors ; /** Original command. Need for reference from Queue completion notification */ - ICommand fCommand; + private final ICommand fCommand; /** Style of this command ( internal coalesced or not) */ - CommandStyle fCmdStyle; + private final CommandStyle fCmdStyle; /** Command being processed for this command */ - CommandInfo fCoalescedCmd; + private CommandInfo fCoalescedCmd; + + private ICommandToken fToken; - public CommandInfo( CommandStyle cmdstyle, ICommand cmd, DataRequestMonitor rm ) { + public CommandInfo(CommandStyle cmdstyle, ICommand cmd, DataRequestMonitor rm ) { fCmdStyle = cmdstyle; fCommand = cmd; fCurrentRequestMonitors = new LinkedList>(); @@ -219,7 +221,7 @@ public class CommandCache implements ICommandListener * does not continue to process it. */ fPendingQCommandsNotYetSent.remove(currentUnsentEntry); - fCommandControl.removeCommand(unsentCommand); + fCommandControl.removeCommand(currentUnsentEntry.fToken); return( coalescedCmdInfo ); } @@ -316,7 +318,7 @@ public class CommandCache implements ICommandListener final CommandInfo finalCachedCmd = cachedCmd; fPendingQCommandsNotYetSent.add(finalCachedCmd); - fCommandControl.queueCommand( + finalCachedCmd.fToken = fCommandControl.queueCommand( finalCachedCmd.getCommand(), new DataRequestMonitor(fSession.getExecutor(), null) { @Override @@ -476,7 +478,7 @@ public class CommandCache implements ICommandListener fCachedContexts.clear(); } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { /* * Do nothing. */ @@ -486,7 +488,7 @@ public class CommandCache implements ICommandListener * (non-Javadoc) * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandQueued(org.eclipse.dd.dsf.mi.core.command.ICommand) */ - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { /* * Do nothing. */ @@ -496,7 +498,7 @@ public class CommandCache implements ICommandListener * (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) */ - public void commandDone(ICommand command, ICommandResult result) { + public void commandDone(ICommandToken token, ICommandResult result) { /* * We handle the done with a runnable where we initiated the command * so there is nothing to do here. @@ -511,11 +513,11 @@ public class CommandCache implements ICommandListener * (non-Javadoc) * @see org.eclipse.dd.dsf.mi.service.control.IDebuggerControl.ICommandListener#commandSent(org.eclipse.dd.dsf.mi.core.command.ICommand) */ - public void commandSent(ICommand command) { + public void commandSent(ICommandToken token) { // Cast the generic ?'s to concrete types in the cache implementation. @SuppressWarnings("unchecked") - ICommand genericCommand = (ICommand)command; + ICommand genericCommand = (ICommand)token.getCommand(); CommandInfo cachedCmd = new CommandInfo( CommandStyle.NONCOALESCED, genericCommand, null) ; diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java index 3d6620338af..6edd9d3f3ce 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandControl.java @@ -17,7 +17,7 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; * and asynchronous events. */ public interface ICommandControl { - + /** * Adds the specified command to the queue of commands to be processed. * @@ -25,7 +25,7 @@ public interface ICommandControl { * @param rm Request completion monitor * @return None */ - void queueCommand(ICommand command, DataRequestMonitor rm); + ICommandToken queueCommand(ICommand command, DataRequestMonitor rm); /** * Removes the specified command from the processor queue. @@ -33,17 +33,7 @@ public interface ICommandControl { * @param command Specific command to be removed * @return None */ - void removeCommand(ICommand command); - - /** - * 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 command); + void removeCommand(ICommandToken token); /** * Adds a notification handler for the Command processor. diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java index 5a2f8e813a6..b4388ae31a1 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandListener.java @@ -18,7 +18,7 @@ public interface ICommandListener { * @return None * @param command Command which has been added to the Queue */ - public void commandQueued(ICommand command); + public void commandQueued(ICommandToken token); /** * Notification that the given command was sent to the debugger. At this @@ -29,7 +29,7 @@ public interface ICommandListener { * @return None * @param command */ - public void commandSent(ICommand command); + public void commandSent(ICommandToken token); /** * Notifies that the specified command has been removed from the @@ -42,7 +42,7 @@ public interface ICommandListener { * @return None * @param Command which has been sent to the backend */ - public void commandRemoved(ICommand command); + public void commandRemoved(ICommandToken token); /** * Notifies that the specified command has been completed. @@ -50,5 +50,5 @@ public interface ICommandListener { * @return None * @param Command which has been sent to the backend */ - public void commandDone(ICommand command, ICommandResult result); + public void commandDone(ICommandToken token, ICommandResult result); } diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandToken.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandToken.java new file mode 100644 index 00000000000..9149af2be42 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/ICommandToken.java @@ -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 getCommand(); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java index 8530ca85543..23dfe15593d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java @@ -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.ICommandListener; 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.service.AbstractDsfService; 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. private static class CommandHandle { + final private ICommandToken fToken; final private AbstractPDACommand fCommand; final private DataRequestMonitor fRequestMonitor; - CommandHandle(AbstractPDACommand c, DataRequestMonitor rm) { + CommandHandle(ICommandToken token, AbstractPDACommand c, DataRequestMonitor rm) { + fToken = token; fCommand = c; fRequestMonitor = rm; } @@ -334,7 +337,13 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon } - public void queueCommand(ICommand command, DataRequestMonitor rm) { + public ICommandToken queueCommand(final ICommand command, DataRequestMonitor rm) { + ICommandToken token = new ICommandToken() { + public ICommand getCommand() { + return command; + } + }; + if (command instanceof AbstractPDACommand) { // Cast from command with "" to a more concrete // type to use internally in the command control. @@ -346,9 +355,9 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon DataRequestMonitor pdaRM = (DataRequestMonitor)rm; // 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) { - listener.commandQueued(command); + listener.commandQueued(token); } // 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(); } }); - } else { PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command); } + return token; } - public void cancelCommand(ICommand command) { - // This debugger is unable of canceling commands once they have - // been sent. - } - - public void removeCommand(ICommand command) { + public void removeCommand(ICommandToken token) { // Removes given command from the queue and notify the listeners for (Iterator itr = fCommandQueue.iterator(); itr.hasNext();) { CommandHandle handle = itr.next(); - if (command.equals(handle.fCommand)) { + if (token.equals(handle.fToken)) { itr.remove(); 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 for (ICommandListener listener : fCommandListeners) { - listener.commandDone(handle.fCommand, result); + listener.commandDone(handle.fToken, result); } // Process next command in queue. @@ -431,7 +435,7 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon // Notify listeners also. 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); PDAPlugin.debug("C: " + handle.fCommand.getRequest()); for (ICommandListener listener : fCommandListeners) { - listener.commandSent(handle.fCommand); + listener.commandSent(handle.fToken); } } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java index f8124f277e8..5d1f330f0d1 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/BasicTests.java @@ -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.ICommandListener; 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.junit.BeforeClass; import org.junit.Test; @@ -53,17 +54,17 @@ public class BasicTests extends CommandControlTestsBase { List fRemovedCommands = new LinkedList(); List fSentCommands = new LinkedList(); - public void commandDone(ICommand command, ICommandResult result) { - fDoneCommands.add(new CommandInfo(command, result)); + public void commandDone(ICommandToken token, ICommandResult result) { + fDoneCommands.add(new CommandInfo(token.getCommand(), result)); } - public void commandQueued(ICommand command) { - fQueuedCommands.add(new CommandInfo(command, null)); + public void commandQueued(ICommandToken token) { + fQueuedCommands.add(new CommandInfo(token.getCommand(), null)); } - public void commandRemoved(ICommand command) { - fRemovedCommands.add(new CommandInfo(command, null)); + public void commandRemoved(ICommandToken token) { + fRemovedCommands.add(new CommandInfo(token.getCommand(), null)); } - public void commandSent(ICommand command) { - fSentCommands.add(new CommandInfo(command, null)); + public void commandSent(ICommandToken token) { + fSentCommands.add(new CommandInfo(token.getCommand(), null)); } void reset() { @@ -106,7 +107,7 @@ public class BasicTests extends CommandControlTestsBase { Query queueRemoveCommandQuery = new Query() { @Override protected void execute(DataRequestMonitor rm) { - fCommandControl.queueCommand( + ICommandToken token = fCommandControl.queueCommand( testCommand, new DataRequestMonitor(fExecutor, null) { @Override @@ -114,7 +115,7 @@ public class BasicTests extends CommandControlTestsBase { Assert.fail("This command should never have been executed."); } }); - fCommandControl.removeCommand(testCommand); + fCommandControl.removeCommand(token); rm.setData(new Object()); rm.done(); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index 7e860d9c7c7..5419f125828 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -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.ICommandListener; 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.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfServicesTracker; @@ -1487,13 +1488,19 @@ public class MIVariableManager implements ICommandControl { }); } - public void queueCommand(final ICommand command, DataRequestMonitor rm) { + public ICommandToken queueCommand(final ICommand command, DataRequestMonitor rm) { + final ICommandToken token = new ICommandToken() { + public ICommand getCommand() { + return command; + } + }; + // 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 // 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. - processCommandSent(command); + processCommandSent(token); if (command instanceof ExprMetaGetVar) { @SuppressWarnings("unchecked") @@ -1512,6 +1519,7 @@ public class MIVariableManager implements ICommandControl { getData().getType(), !getData().isComplex())); drm.done(); + processCommandDone(token, drm.getData()); } }); } else if (command instanceof ExprMetaGetAttributes) { @@ -1530,6 +1538,7 @@ public class MIVariableManager implements ICommandControl { protected void handleSuccess() { drm.setData(new ExprMetaGetAttributesInfo(getData())); drm.done(); + processCommandDone(token, drm.getData()); } }); } @@ -1555,6 +1564,7 @@ public class MIVariableManager implements ICommandControl { drm.setData( new ExprMetaGetValueInfo(getData().getFormattedValue())); drm.done(); + processCommandDone(token, drm.getData()); } }); } @@ -1577,6 +1587,7 @@ public class MIVariableManager implements ICommandControl { protected void handleSuccess() { drm.setData(new ExprMetaGetChildrenInfo(getData())); drm.done(); + processCommandDone(token, drm.getData()); } }); } @@ -1598,6 +1609,7 @@ public class MIVariableManager implements ICommandControl { protected void handleSuccess() { drm.setData(new ExprMetaGetChildCountInfo(getData())); 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, "Unexpected Expression Meta command", null)); //$NON-NLS-1$ rm.done(); - } + } + return token; } /* @@ -1621,7 +1634,7 @@ public class MIVariableManager implements ICommandControl { * (non-Javadoc) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand) */ - public void removeCommand(ICommand command) { + public void removeCommand(ICommandToken token) { // It is impossible to remove a command from the MIVariableManager. // This should never be called, if we did things right. assert false; @@ -1637,19 +1650,24 @@ public class MIVariableManager implements ICommandControl { * (non-Javadoc) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#cancelCommand(org.eclipse.dd.mi.service.command.commands.ICommand) */ - public void cancelCommand(ICommand command) {} public void addCommandListener(ICommandListener processor) { fCommandProcessors.add(processor); } public void removeCommandListener(ICommandListener processor) { fCommandProcessors.remove(processor); } public void addEventListener(IEventListener processor) {} public void removeEventListener(IEventListener processor) {} - private void processCommandSent(ICommand command) { + private void processCommandSent(ICommandToken token) { 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() { MIRootVariableObject root; while ((root = updatedRootList.poll()) != null) { @@ -1679,5 +1697,4 @@ public class MIVariableManager implements ICommandControl { // The views will fully refresh on a MemoryChangedEvent markAllOutOfDate(); } - } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java index 1fe0c72b4d7..6a0ecedc0be 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractCLIProcess.java @@ -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.ICommandListener; 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.service.DsfSession; import org.eclipse.dd.mi.internal.MIPlugin; @@ -204,11 +205,12 @@ public abstract class AbstractCLIProcess extends Process } } - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { // Ignore } - public void commandSent(ICommand 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. if (command instanceof CLICommand && !(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole)) @@ -217,12 +219,13 @@ public abstract class AbstractCLIProcess extends Process } } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { // Ignore } - public void commandDone(ICommand command, ICommandResult result) { - if (command instanceof CLICommand && + public void commandDone(ICommandToken token, ICommandResult result) { + ICommand command = token.getCommand(); + if (token.getCommand() instanceof CLICommand && !(command instanceof ProcessCLICommand || command instanceof ProcessMIInterpreterExecConsole)) { fSuppressConsoleOutputCounter--; diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java index 62a6be29442..4fa55ea69cb 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/AbstractMIControl.java @@ -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.ICommandListener; 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.service.AbstractDsfService; 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) */ - public void queueCommand(ICommand command, DataRequestMonitor rm) { + public ICommandToken queueCommand(final ICommand command, DataRequestMonitor 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 // thrown if the client did not give an MI command as an argument. @SuppressWarnings("unchecked") @@ -202,8 +196,12 @@ public abstract class AbstractMIControl extends AbstractDsfService DataRequestMonitor miDone = (DataRequestMonitor)rm; 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 @@ -238,7 +236,7 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle cmdHandle = new CommandHandle( new MIThreadSelect(handle.fCommand.getContext(), fCurrentThreadId), null); 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 @@ -251,12 +249,13 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle cmdHandle = new CommandHandle( new MIStackSelectFrame(handle.fCommand.getContext(), fCurrentStackLevel), null); 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); } } + return handle; } /* @@ -267,12 +266,12 @@ public abstract class AbstractMIControl extends AbstractDsfService * (non-Javadoc) * @see org.eclipse.dd.mi.service.command.IDebuggerControl#removeCommand(org.eclipse.dd.mi.service.command.commands.ICommand) */ - public void removeCommand(ICommand command) { + public void removeCommand(ICommandToken token) { synchronized(fCommandQueue) { for ( CommandHandle handle : fCommandQueue ) { - if ( handle.getCommand().equals(command)) { + if ( handle.equals(token)) { fCommandQueue.remove(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 command) {} - /* * Allows a user ( typically a cache manager ) to sign up a listener to monitor command queue * activity. @@ -339,19 +326,19 @@ public abstract class AbstractMIControl extends AbstractDsfService private void processCommandQueued(CommandHandle commandHandle) { for (ICommandListener processor : fCommandProcessors) { - processor.commandQueued(commandHandle.getCommand()); + processor.commandQueued(commandHandle); } } private void processCommandRemoved(CommandHandle commandHandle) { for (ICommandListener processor : fCommandProcessors) { - processor.commandRemoved(commandHandle.getCommand()); + processor.commandRemoved(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) { - 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. */ 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. * Unless the value wraps around which is unlikely. */ + private int fTokenIdCounter = 0 ; - private static int globalCounter = 0 ; - - private static synchronized int getUniqToken() { - int count = ++globalCounter; + private int getNewTokenId() { + int count = ++fTokenIdCounter; // If we ever wrap around. if (count <= 0) { - count = globalCounter = 1; + count = fTokenIdCounter = 1; } return count; } @@ -406,8 +392,8 @@ public abstract class AbstractMIControl extends AbstractDsfService * individual request. */ - public static class CommandHandle { - + private class CommandHandle implements ICommandToken { + private MICommand fCommand; private DataRequestMonitor fRequestMonitor; private int fTokenId ; @@ -415,12 +401,13 @@ public abstract class AbstractMIControl extends AbstractDsfService CommandHandle(MICommand c, DataRequestMonitor d) { fCommand = c; fRequestMonitor = d; - fTokenId = getUniqToken() ; + fTokenId = getNewTokenId() ; } public MICommand getCommand() { return fCommand; } public DataRequestMonitor getRequestMonitor() { return fRequestMonitor; } - public Integer getToken() { return fTokenId; } + public Integer getTokenId() { return fTokenId; } + //public String getThreadId() { return null; } public Integer getStackFrameId() { 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. */ - fRxCommands.put(commandHandle.getToken(), commandHandle); + fRxCommands.put(commandHandle.getTokenId(), commandHandle); } /* * 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 { if (fOutputStream != null) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java index c2af69c36d4..9beca3818fb 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/CLIEventProcessor.java @@ -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.IRunControl.IContainerDMContext; 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.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; 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.MIInterpreterExecConsole; @@ -73,30 +73,30 @@ public class CLIEventProcessor fCommandControl.removeEventListener(this); } - public void commandSent(ICommand command) { - if (command instanceof CLICommand) { - processStateChanges( (CLICommand)command ); + public void commandSent(ICommandToken token) { + if (token.getCommand() instanceof CLICommand) { + processStateChanges( (CLICommand)token.getCommand() ); } - else if (command instanceof MIInterpreterExecConsole) { - processStateChanges( (MIInterpreterExecConsole)command ); + else if (token.getCommand() instanceof MIInterpreterExecConsole) { + processStateChanges( (MIInterpreterExecConsole)token.getCommand() ); } } - public void commandDone(ICommand command, ICommandResult result) { - if (command instanceof CLICommand) { - processSettingChanges( (CLICommand)command ); + public void commandDone(ICommandToken token, ICommandResult result) { + if (token.getCommand() instanceof CLICommand) { + processSettingChanges( (CLICommand)token.getCommand() ); } - else if (command instanceof MIInterpreterExecConsole) { - processSettingChanges( (MIInterpreterExecConsole)command ); + else if (token.getCommand() instanceof MIInterpreterExecConsole) { + processSettingChanges( (MIInterpreterExecConsole)token.getCommand() ); } fEventList.clear(); } - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { // No action } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { // No action } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java index 8455061d919..3e0c9e7eb54 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIInferiorProcess.java @@ -32,9 +32,9 @@ import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; 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.ICommandResult; +import org.eclipse.dd.dsf.debug.service.command.ICommandToken; import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.mi.internal.MIPlugin; @@ -387,22 +387,22 @@ public class MIInferiorProcess extends Process } } - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { // No action } - public void commandSent(ICommand command) { - if (command instanceof CLICommand) { + public void commandSent(ICommandToken token) { + if (token.getCommand() instanceof CLICommand) { fSuppressTargetOutputCounter++; } } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { // No action } - public void commandDone(ICommand command, ICommandResult result) { - if (command instanceof CLICommand) { + public void commandDone(ICommandToken token, ICommandResult result) { + if (token.getCommand() instanceof CLICommand) { fSuppressTargetOutputCounter--; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java index c64069a42d9..23b9335dd83 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java @@ -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.ICommandListener; 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.service.DsfServicesTracker; import org.eclipse.dd.mi.internal.MIPlugin; @@ -177,19 +178,20 @@ public class MIRunControlEventProcessor return event; } - public void commandQueued(ICommand command) { + public void commandQueued(ICommandToken token) { // Do nothing. } - public void commandSent(ICommand command) { + public void commandSent(ICommandToken token) { // Do nothing. } - public void commandRemoved(ICommand command) { + public void commandRemoved(ICommandToken token) { // Do nothing. } - public void commandDone(ICommand cmd, ICommandResult result) { + public void commandDone(ICommandToken token, ICommandResult result) { + ICommand cmd = token.getCommand(); MIInfo cmdResult = (MIInfo) result ; MIOutput output = cmdResult.getMIOutput(); MIResultRecord rr = output.getMIResultRecord();