blob: a5b5945b5da748dfad0804f88f29a4f698fdc57c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 The Regents of the University of California.
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly marked,
* so as not to confuse it with the version available from LANL.
*
* Additionally, 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
*
* LA-CC 04-115
*******************************************************************************/
package org.eclipse.ptp.debug.external.core;
import java.util.ArrayList;
import java.util.List;
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.ptp.core.util.BitList;
import org.eclipse.ptp.debug.core.IAbstractDebugger;
import org.eclipse.ptp.debug.core.IDebugCommand;
import org.eclipse.ptp.debug.core.PDebugUtils;
import org.eclipse.ptp.debug.core.cdi.PCDIException;
/**
* @author Clement chu
*
*/
public class DebugCommandQueue extends Job {
private List<IDebugCommand> queue = new ArrayList<IDebugCommand>();
private boolean terminated = false;
private boolean stopAddCommand = false;
private IDebugCommand currentCommand = null;
private IAbstractDebugger debugger = null;
private IDebugCommand interruptCommand = null;
public DebugCommandQueue(IAbstractDebugger debugger) {
super("Debug Command Queue");
this.debugger = debugger;
setPriority(Job.SHORT);
setSystem(true);
}
public synchronized boolean isTerminated() {
return terminated;
}
public synchronized void setTerminated() {
terminated = true;
doFlushCommands(false);
}
public synchronized void setStopAddCommand(boolean stopAddCommand) {
this.stopAddCommand = stopAddCommand;
}
public synchronized void setInterruptCommand(IDebugCommand interruptCommand) {
this.interruptCommand = interruptCommand;
}
public synchronized IDebugCommand getInterruptCommand() {
return interruptCommand;
}
protected IStatus run(IProgressMonitor monitor) {
while (!queue.isEmpty()) {
try {
currentCommand = getCommand();
if (terminated) {
currentCommand.doFlush();
break;
}
PDebugUtils.println("*** SEND COMMAND: " + currentCommand.getCommandName() + ", tasks: " + AbstractDebugger.showBitList(currentCommand.getTasks()));
currentCommand.execCommand(debugger);
} catch (PCDIException e) {
debugger.handleErrorEvent(currentCommand.getTasks(), e.getMessage(), e.getErrorCode());
currentCommand.doFlush();
}
finally {
currentCommand = null;
}
}
return Status.OK_STATUS;
}
/*
private boolean waitForCommand() {
synchronized (queue) {
try {
if (currentCommand != null || queue.isEmpty()) {
queue.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
return true;
}
}
*/
private IDebugCommand getCommand() throws PCDIException {
synchronized (queue) {
if (!queue.isEmpty()) {
return (IDebugCommand) queue.remove(0);
}
}
throw new PCDIException("No DebugCommand found");
}
public void addCommand(IDebugCommand command) {
synchronized (queue) {
if (command == null)
return;
if (!stopAddCommand && !terminated && !contains(command)) {
if (currentCommand != null && currentCommand.canInterrupt()) {
if (!command.canInterrupt()) {
command.doFlush();
return;
}
}
if (command.isWaitInQueue()) {
queue.add(command);
//addCommandByPriority(command);
}
else {
PDebugUtils.println("************ DebugCommandQueue -- Add cmd JUMP: " + command.getCommandName());
//jump the queue
queue.add(0, command);
}
/*
if (command.canInterrupt() && currentCommand != null) {
//only do flush if the current command cannot interrupt
if (!currentCommand.canInterrupt()) {
currentCommand.doFlush();
}
}
*/
schedule();
}
else {
command.doFlush();
if (stopAddCommand || terminated) {
PDebugUtils.println("************ ERROR in DebugCommandQueue -- debugger is terminated or stoped to add command, cmd: " + command.getCommandName());
}
else {
//TODO how to deal with duplicate command
PDebugUtils.println("************ ERROR in DebugCommandQueue -- duplicate, cmd: " + command.getCommandName());
}
}
}
}
/*
private void addCommandByPriority(IDebugCommand command) {
synchronized (queue) {
if (command.getPriority() > IDebugCommand.PRIORITY_L) {
for (int i=0; i<queue.size(); i++) {
if (((IDebugCommand)queue.get(i)).getPriority() < command.getPriority()) {
PDebugUtils.println("************ DebugCommandQueue -- add cmd INSERT: " + command.getCommandName());
queue.add(i, command);
return;
}
}
}
PDebugUtils.println("************ DebugCommandQueue -- add cmd LAST: " + command.getCommandName());
queue.add(command);
}
}
*/
private boolean contains(IDebugCommand command) {
synchronized (queue) {
//if (currentCommand != null && currentCommand.compareTo(command) == 0)
//return true;
int size = queue.size();
if (size > 0) {
//return (((IDebugCommand)queue.get(size-1)).compareTo(command) == 0);
return (((IDebugCommand)queue.get(size-1)).equals(command));
}
return false;
}
}
public IDebugCommand[] getCommands() {
return (IDebugCommand[])queue.toArray(new IDebugCommand[0]);
}
public void setCommandReturn(BitList tasks, Object result) {
synchronized (queue) {
if (currentCommand != null) {
PDebugUtils.println("*** SET COMMAND RETURN: " + currentCommand.getCommandName() + ", result: " + result + ", tasks: " + AbstractDebugger.showBitList(tasks));
currentCommand.setReturn(tasks, result);
}
}
}
public IDebugCommand getCurrentCommand() {
return currentCommand;
}
private void doFlushCommands(boolean removeInterrupt) {
synchronized (queue) {
IDebugCommand[] commands = getCommands();
for (int i=commands.length-1; i>-1; i--) {
if (removeInterrupt || !commands[i].canInterrupt()) {
removeCommand(commands[i]);
}
}
}
}
private void removeCommand(IDebugCommand command) {
synchronized (queue) {
command.doFlush();
queue.remove(command);
}
}
public void cleanup(boolean removeInterrupt) {
synchronized (queue) {
doFlushCommands(removeInterrupt);
if (currentCommand != null) {
currentCommand.doFlush();
currentCommand = null;
}
}
}
}