1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 18:05:33 +02:00

Redo the event dispatch now a permanent thread is use to

dispatch events.
This commit is contained in:
Alain Magloire 2002-08-15 05:58:08 +00:00
parent b8c5ededb8
commit 1354f9e661
21 changed files with 312 additions and 183 deletions

View file

@ -0,0 +1,53 @@
/*
* (c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*/
package org.eclipse.cdt.debug.mi.core;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.debug.mi.core.command.Command;
/**
* Simple thread-safe Queue implemetation.
*/
public class CommandQueue extends Queue{
public CommandQueue() {
super();
}
public Command removeCommand(int id) {
//print("in removeCommand(" + id + ") - entering");
synchronized (list) {
int size = list.size();
for (int i = 0; i < size; i++) {
Command cmd = (Command)list.get(i);
int token = cmd.getToken();
if (token == id) {
list.remove(cmd);
return cmd;
}
}
}
return null;
}
public Command removeCommand() throws InterruptedException {
//print("in removeCommand() - entering");
return (Command)removeItem();
}
public void addCommand(Command cmd) {
//print("in addCommand() - entering");
addItem(cmd);
}
private static void print(String msg) {
String name = Thread.currentThread().getName();
System.out.println(name + ": " + msg);
}
}

View file

@ -0,0 +1,50 @@
/*
* (c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*/
package org.eclipse.cdt.debug.mi.core;
import java.io.IOException;
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
/**
* Transmission command thread blocks on the command Queue
* and wake cmd are available and push them to gdb out channel.
*/
public class EventThread extends Thread {
MISession session;
public EventThread(MISession s) {
super("MI Event Thread");
session = s;
}
public void run () {
try {
while (true) {
MIEvent event = null;
Queue eventQueue = session.getEventQueue();
// removeItem() will block until an item is available.
try {
event = (MIEvent)eventQueue.removeItem();
} catch (InterruptedException e) {
// signal by the session of time to die.
if (session.getChannelOutputStream() == null) {
throw new IOException();
}
//e.printStackTrace();
}
try {
session.notifyObservers(event);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
//e.printStackTrace();
}
}
}

View file

@ -8,6 +8,7 @@ import org.eclipse.cdt.debug.mi.core.command.CLICommand;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIExecAbort;
import org.eclipse.cdt.debug.mi.core.command.MIGDBShowExitCode;
import org.eclipse.cdt.debug.mi.core.event.MIInferiorExitEvent;
import org.eclipse.cdt.debug.mi.core.output.MIGDBShowExitCodeInfo;
/**
@ -18,7 +19,7 @@ import org.eclipse.cdt.debug.mi.core.output.MIGDBShowExitCodeInfo;
* To enable and disable the creation of type comments go to
* Window>Preferences>Java>Code Generation.
*/
public class MIProcess extends Process {
public class MIInferior extends Process {
public final static int SUSPENDED = 1;
public final static int RUNNING = 2;
@ -29,7 +30,7 @@ public class MIProcess extends Process {
MISession session;
OutputStream out;
MIProcess(MISession mi) {
MIInferior(MISession mi) {
session = mi;
out = new OutputStream() {
StringBuffer buf = new StringBuffer();
@ -39,6 +40,8 @@ public class MIProcess extends Process {
flush();
}
}
// Encapsulate the string sent to gdb in a fake command.
// and post it to the TxThread.
public void flush() throws IOException {
CLICommand cmd = new CLICommand(buf.toString()) {
public void setToken(int token) {
@ -113,16 +116,13 @@ public class MIProcess extends Process {
if (!isTerminated()) {
CommandFactory factory = session.getCommandFactory();
MIExecAbort abort = factory.createMIExecAbort();
CLICommand yes = new CLICommand("yes") {
public void setToken() { }
};
try {
session.postCommand(abort);
session.postCommand(yes);
setTerminated();
session.getRxThread().fireEvent(new MIInferiorExitEvent());
} catch (MIException e) {
}
}
// Do not wait for answer.
}
public synchronized boolean isSuspended() {

View file

@ -48,7 +48,7 @@ public class MIPlugin extends Plugin {
}
public ICDISession createCSession(String program) throws IOException {
String[]args = new String[]{"gdb", "--quiet", "-i", "mi", program};
String[]args = new String[]{"gdb", "-q", "-i", "mi", program};
Process gdb = Runtime.getRuntime().exec(args);
MISession session = createMISession(gdb.getInputStream(), gdb.getOutputStream());
/*

View file

@ -13,6 +13,8 @@ import java.util.Observable;
import org.eclipse.cdt.debug.mi.core.command.Command;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIGDBExit;
import org.eclipse.cdt.debug.mi.core.command.MIGDBSet;
import org.eclipse.cdt.debug.mi.core.output.MIOutput;
import org.eclipse.cdt.debug.mi.core.output.MIParser;
@ -27,11 +29,13 @@ public class MISession extends Observable {
InputStream inChannel;
OutputStream outChannel;
Thread txThread;
Thread rxThread;
TxThread txThread;
RxThread rxThread;
EventThread eventThread;
Queue txQueue;
Queue rxQueue;
CommandQueue txQueue;
CommandQueue rxQueue;
Queue eventQueue;
PipedInputStream miInPipe;
PipedOutputStream miOutPipe;
@ -46,7 +50,7 @@ public class MISession extends Observable {
long cmdTimeout = 10000; // 10 * 1000 (~ 10 secs);
MIProcess process;
MIInferior inferior;
/**
* Create the gdb session.
@ -59,12 +63,15 @@ public class MISession extends Observable {
outChannel = o;
factory = new CommandFactory();
parser = new MIParser();
txQueue = new Queue();
rxQueue = new Queue();
txQueue = new CommandQueue();
rxQueue = new CommandQueue();
eventQueue = new Queue();
txThread = new TxThread(this);
rxThread = new RxThread(this);
eventThread = new EventThread(this);
txThread.start();
rxThread.start();
eventThread.start();
try {
miOutPipe = new PipedOutputStream();
@ -76,7 +83,11 @@ public class MISession extends Observable {
} catch (IOException e) {
}
process = new MIProcess(this);
inferior = new MIInferior(this);
try {
postCommand(new MIGDBSet(new String[]{"confirm", "off"}));
} catch (MIException e) {
}
}
/**
@ -157,25 +168,35 @@ public class MISession extends Observable {
public void postCommand(Command cmd, long timeout) throws MIException {
MIPlugin.getDefault().debugLog(cmd.toString());
// Test if we in a sane state.
if (!txThread.isAlive() || !rxThread.isAlive()) {
throw new MIException("{R,T}xThread terminated");
}
txQueue.addCommand(cmd);
// Wait for the response or timedout
synchronized (cmd) {
// RxThread will set the MIOutput on the cmd
// when the response arrive.
while (cmd.getMIOutput() == null) {
try {
cmd.wait(timeout);
break; // Timeout or Notify
} catch (InterruptedException e) {
// Do not wait for command if time out is 0
if (timeout > 0) {
// RxThread will set the MIOutput on the cmd
// when the response arrive.
while (cmd.getMIOutput() == null) {
try {
cmd.wait(timeout);
if (cmd.getMIOutput() == null) {
throw new MIException("Timedout");
}
} catch (InterruptedException e) {
}
}
}
}
}
public MIProcess getMIProcess() {
return process;
public MIInferior getMIInferior() {
return inferior;
}
public boolean isTerminated() {
@ -187,9 +208,17 @@ public class MISession extends Observable {
*/
public void terminate() {
process.destroy();
// Destroy any MI Inferior
inferior.destroy();
// Closing the channel will kill the RxThread.
// send the exit.
try {
MIGDBExit exit = factory.createMIGDBExit();
postCommand(exit);
} catch (MIException e) {
}
// Explicitely close the channels
try {
inChannel.close();
} catch (IOException e) {
@ -200,9 +229,10 @@ public class MISession extends Observable {
outChannel.close();
} catch (IOException e) {
}
// This is __needed__ to stop the txThread.
// This is __needed__ to stop the txThread and eventThread.
outChannel = null;
// Make sure all threads are gone.
try {
if (txThread.isAlive()) {
txThread.interrupt();
@ -218,6 +248,14 @@ public class MISession extends Observable {
rxThread.join();
} catch (InterruptedException e) {
}
try {
if (eventThread.isAlive()) {
eventThread.interrupt();
}
eventThread.join();
} catch (InterruptedException e) {
}
}
/**
@ -241,14 +279,22 @@ public class MISession extends Observable {
return logOutPipe;
}
Queue getTxQueue() {
CommandQueue getTxQueue() {
return txQueue;
}
Queue getRxQueue() {
CommandQueue getRxQueue() {
return rxQueue;
}
Queue getEventQueue() {
return eventQueue;
}
RxThread getRxThread() {
return rxThread;
}
InputStream getChannelInputStream() {
return inChannel;
}

View file

@ -8,65 +8,47 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.debug.mi.core.command.Command;
/**
* Simple thread-safe Queue implemetation.
*/
public class Queue {
private List list;
protected List list;
public Queue() {
list = Collections.synchronizedList(new LinkedList());
}
public Command removeCommand(int id) {
//print("in removeCommand(" + id + ") - entering");
synchronized (list) {
int size = list.size();
for (int i = 0; i < size; i++) {
Command cmd = (Command)list.get(i);
int token = cmd.getToken();
if (token == id) {
list.remove(cmd);
return cmd;
}
}
}
return null;
}
public Command removeCommand() throws InterruptedException {
//print("in removeCommand() - entering");
public Object removeItem() throws InterruptedException {
//print("in removeItem() - entering");
synchronized (list) {
while (list.isEmpty()) {
//print("in removeCommand() - about to wait()");
//print("in removeItem() - about to wait()");
list.wait();
//print("in removeCommand() - done with wait()");
//print("in removeItem() - done with wait()");
}
// extract the new first cmd
Command cmd = (Command)list.remove(0);
Object item = list.remove(0);
//print("in removeCommand() - leaving");
return cmd;
//print("in removeItem() - leaving");
return item;
}
}
public void addCommand(Command cmd) {
//print("in addCommand() - entering");
public void addItem(Object item) {
//print("in addItem() - entering");
synchronized (list) {
// There will always be room to add to this List
// because it expands as needed.
list.add(cmd);
//print("in addCommand - just added: '" + cmd + "'");
list.add(item);
//print("in addItem - just added: '" + cmd + "'");
// After adding, notify any and all waiting
// threads that the list has changed.
list.notifyAll();
//print("in addCommand() - just notified");
//print("in addItem() - just notified");
}
//print("in addCommand() - leaving");
//print("in addItem() - leaving");
}
private static void print(String msg) {

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.debug.mi.core.command.MIExecNextInstruction;
import org.eclipse.cdt.debug.mi.core.command.MIExecStep;
import org.eclipse.cdt.debug.mi.core.command.MIExecStepInstruction;
import org.eclipse.cdt.debug.mi.core.command.MIExecUntil;
import org.eclipse.cdt.debug.mi.core.event.EventThread;
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointEvent;
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
import org.eclipse.cdt.debug.mi.core.event.MIExitEvent;
@ -68,30 +67,12 @@ public class RxThread extends Thread {
while (true) {
String line;
while ((line = reader.readLine()) != null) {
// Testing on GNU/Linux where target stream output
// is entertwine with MI out,
// comment out the if/else below and just use:
// processMIOutput(line);
// at least for testing.
// We accumulate until we see the gdb terminator.
MIPlugin.getDefault().debugLog(line);
if (line.startsWith(MIOutput.terminator)) {
// discard termination
processMIOutput(buffer.toString());
buffer = new StringBuffer();
} else if (line.startsWith(MITargetStreamOutput.startTag)) {
// Process Target output immediately.
processMIOutput(line + "\n");
} else {
buffer.append(line).append('\n');
}
processMIOutput(line + "\n");
}
}
} catch (IOException e) {
MIEvent event = new MIExitEvent();
Thread eventTread = new EventThread(session, new MIEvent[]{event});
eventTread.start();
fireEvent(new MIExitEvent());
//e.printStackTrace();
}
}
@ -106,7 +87,7 @@ MIPlugin.getDefault().debugLog(line);
MIOutput response = session.parse(buffer);
if (response != null) {
List list = new ArrayList();
Queue rxQueue = session.getRxQueue();
CommandQueue rxQueue = session.getRxQueue();
// Notify any command waiting for a ResultRecord.
MIResultRecord rr = response.getMIResultRecord();
@ -135,11 +116,11 @@ MIPlugin.getDefault().debugLog(line);
} else {
type = MIRunningEvent.CONTINUE;
}
session.getMIProcess().setRunning();
session.getMIInferior().setRunning();
MIEvent event = new MIRunningEvent(type);
fireEvents(new MIEvent[]{event});
fireEvent(event);
} else if ("exit".equals(state)) {
session.getMIProcess().setTerminated();
session.getMIInferior().setTerminated();
}
// Notify the waiting command.
@ -180,11 +161,12 @@ MIPlugin.getDefault().debugLog(line);
void processMIOOBRecord(MIAsyncRecord async, List list) {
if (async instanceof MIExecAsyncOutput) {
MIExecAsyncOutput exec = (MIExecAsyncOutput)async;
MIEvent e = null;
// Change of state.
String state = exec.getAsyncClass();
if ("stopped".equals(state)) {
session.getMIProcess().setSuspended();
session.getMIInferior().setSuspended();
}
MIResult[] results = exec.getMIResults();
@ -194,13 +176,22 @@ MIPlugin.getDefault().debugLog(line);
if (var.equals("reason")) {
if (val instanceof MIConst) {
String reason = ((MIConst)val).getString();
MIEvent e = createEvent(reason, exec);
e = createEvent(reason, exec);
if (e != null) {
list.add(e);
}
}
}
}
// HACK: GDB for temporary breakpoints will not send the
// "reason" ??? Fake this as breakpoint-hit
if (e == null) {
e = createEvent("breakpoint-hit", exec);
if (e != null) {
list.add(e);
}
}
} else if (async instanceof MIStatusAsyncOutput) {
// Nothing done .. but what about +download??
} else if (async instanceof MINotifyAsyncOutput) {
@ -318,19 +309,25 @@ MIPlugin.getDefault().debugLog(line);
event = new MIFunctionFinishedEvent(rr);
}
} else if ("exited-normally".equals(reason)) {
session.getMIProcess().setTerminated();
session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent();
} else if ("exited-signalled".equals(reason)) {
session.getMIProcess().setTerminated();
session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent();
} else if ("exited".equals(reason)) {
session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent();
}
return event;
}
public void fireEvents(MIEvent[] events) {
if (events.length > 0) {
Thread eventTread = new EventThread(session, events);
eventTread.start();
for (int i = 0; i < events.length; i++) {
fireEvent(events[i]);
}
}
public void fireEvent(MIEvent event) {
session.getEventQueue().addItem(event);
}
}

View file

@ -30,7 +30,7 @@ public class TxThread extends Thread {
try {
while (true) {
Command cmd = null;
Queue txQueue = session.getTxQueue();
CommandQueue txQueue = session.getTxQueue();
// removeCommand() will block until a command is available.
try {
cmd = txQueue.removeCommand();
@ -54,7 +54,7 @@ public class TxThread extends Thread {
// a valid token, this is to permit input(HACK!)
// or commands that do not want to wait for responses.
if (cmd.getToken() > 0) {
Queue rxQueue = session.getRxQueue();
CommandQueue rxQueue = session.getRxQueue();
rxQueue.addCommand(cmd);
}
}

View file

@ -30,8 +30,10 @@ import org.eclipse.cdt.debug.mi.core.command.MIExecRun;
import org.eclipse.cdt.debug.mi.core.command.MIExecStep;
import org.eclipse.cdt.debug.mi.core.command.MIExecStepInstruction;
import org.eclipse.cdt.debug.mi.core.command.MITargetDetach;
import org.eclipse.cdt.debug.mi.core.command.MIThreadListIds;
import org.eclipse.cdt.debug.mi.core.output.MIDataEvaluateExpressionInfo;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.cdt.debug.mi.core.output.MIThreadListIdsInfo;
/**
*/
@ -57,6 +59,16 @@ public class CTarget implements ICDITarget {
threadList.remove(cthread);
}
boolean containsCThread(int id) {
for (int i = 0; i < threadList.size(); i++) {
CThread cthread = (CThread)threadList.get(i);
if (cthread.getId() == id) {
return true;
}
}
return false;
}
CThread[] getCThreads() {
return (CThread[])threadList.toArray(new CThread[threadList.size()]);
}
@ -109,7 +121,7 @@ public class CTarget implements ICDITarget {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#getProcess()
*/
public Process getProcess() {
return session.getMISession().getMIProcess();
return session.getMISession().getMIInferior();
}
/**
@ -144,7 +156,29 @@ public class CTarget implements ICDITarget {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#getThreads()
*/
public ICDIThread[] getThreads() throws CDIException {
return new ICDIThread[0];
MISession mi = session.getMISession();
CommandFactory factory = mi.getCommandFactory();
MIThreadListIds tids = factory.createMIThreadListIds();
try {
mi.postCommand(tids);
MIThreadListIdsInfo info = tids.getMIThreadListIdsInfo();
int[] ids = info.getThreadIds();
if (ids != null && ids.length > 0) {
for (int i = 0; i < ids.length; i++) {
if (! containsCThread(ids[i])) {
addCThread(new CThread(this, ids[i]));
}
}
} else {
// HACK create a dummy thread
if (threadList.size() == 0) {
addCThread(new CThread(this, 1));
}
}
} catch (MIException e) {
throw new CDIException(e.toString());
}
return (ICDIThread[])getCThreads();
}
/**
@ -158,21 +192,21 @@ public class CTarget implements ICDITarget {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isStepping()
*/
public boolean isStepping() {
return session.getMISession().getMIProcess().isRunning();
return session.getMISession().getMIInferior().isRunning();
}
/**
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isSuspended()
*/
public boolean isSuspended() {
return session.getMISession().getMIProcess().isSuspended();
return session.getMISession().getMIInferior().isSuspended();
}
/**
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isTerminated()
*/
public boolean isTerminated() {
return session.getMISession().getMIProcess().isTerminated();
return session.getMISession().getMIInferior().isTerminated();
}
/**
@ -198,7 +232,9 @@ public class CTarget implements ICDITarget {
*/
public void resume() throws CDIException {
MISession mi = session.getMISession();
if (mi.getMIProcess().isSuspended()) {
if (mi.getMIInferior().isRunning() || mi.getMIInferior().isStepping()) {
throw new CDIException("Inferior already running");
} else if (mi.getMIInferior().isSuspended()) {
CommandFactory factory = mi.getCommandFactory();
MIExecContinue cont = factory.createMIExecContinue();
try {
@ -210,8 +246,11 @@ public class CTarget implements ICDITarget {
} catch (MIException e) {
throw new CDIException(e.toString());
}
} else if (mi.getMIInferior().isTerminated()) {
restart();
} else {
restart();
//throw new CDIException("Unknow state");
}
}
@ -309,7 +348,7 @@ public class CTarget implements ICDITarget {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#terminate()
*/
public void terminate() throws CDIException {
session.getMISession().getMIProcess().destroy();
session.getMISession().getMIInferior().destroy();
}
/**

View file

@ -6,9 +6,9 @@ import org.eclipse.cdt.debug.core.cdi.model.ICDIThread;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MISession;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIStackListFrames;
import org.eclipse.cdt.debug.mi.core.command.MIStackListArguments;
import org.eclipse.cdt.debug.mi.core.output.MIFrame;
import org.eclipse.cdt.debug.mi.core.output.MIStackListFramesInfo;
import org.eclipse.cdt.debug.mi.core.output.MIStackListArgumentsInfo;
/**
* @author alain
@ -32,7 +32,7 @@ public class CThread extends CObject implements ICDIThread {
}
public String toString() {
return "thread-" + Integer.toString(id);
return Integer.toString(id);
}
/**
@ -48,10 +48,12 @@ public class CThread extends CObject implements ICDIThread {
public ICDIStackFrame[] getStackFrames() throws CDIException {
MISession mi = getCTarget().getCSession().getMISession();
CommandFactory factory = mi.getCommandFactory();
MIStackListFrames frames = factory.createMIStackListFrames();
//MIStackListFrames frames = factory.createMIStackListFrames();
MIStackListArguments frames = factory.createMIStackListArguments(true);
try {
mi.postCommand(frames);
MIStackListFramesInfo info = frames.getMIStackListFramesInfo();
//MIStackListFramesInfo info = frames.getMIStackListFramesInfo();
MIStackListArgumentsInfo info = frames.getMIStackListArgumentsInfo();
if (info == null) {
throw new CDIException("Timedout");
}

View file

@ -34,12 +34,10 @@ public class EventManager extends SessionObject implements ICDIEventManager {
public CDIObserver(ICDIEventListener l) {
listener = l;
}
public void update(Observable o, Object args) {
MIEvent[] events = (MIEvent[])args;
for (int i = 0; i < events.length; i++) {
ICDIEvent cdiEvent = EventAdapter.getCDIEvent(getCSession(), events[i]);
listener.handleDebugEvent(cdiEvent);
}
public void update(Observable o, Object arg) {
MIEvent event = (MIEvent)arg;
ICDIEvent cdiEvent = EventAdapter.getCDIEvent(getCSession(), event);
listener.handleDebugEvent(cdiEvent);
}
}

View file

@ -34,14 +34,14 @@ public class Variable extends CObject implements ICDIVariable {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getTypeName()
*/
public String getTypeName() throws CDIException {
return null;
return "";
}
/**
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getValue()
*/
public ICDIValue getValue() throws CDIException {
return null;
return new Value(getCTarget(), arg.getValue());
}
/**

View file

@ -49,6 +49,10 @@ public class MIStackListArguments extends MICommand
setParameters(params);
}
public MIStackListArgumentsInfo getMIStackListArgumentsInfo() throws MIException {
return (MIStackListArgumentsInfo)getMIInfo();
}
public MIInfo getMIInfo() throws MIException {
MIInfo info = null;
MIOutput out = getMIOutput();

View file

@ -25,6 +25,10 @@ public class MIThreadListIds extends MICommand
super("-thread-list-ids");
}
public MIThreadListIdsInfo getMIThreadListIdsInfo() throws MIException {
return (MIThreadListIdsInfo)getMIInfo();
}
public MIInfo getMIInfo() throws MIException {
MIInfo info = null;
MIOutput out = getMIOutput();

View file

@ -1,27 +0,0 @@
package org.eclipse.cdt.debug.mi.core.event;
import org.eclipse.cdt.debug.mi.core.MISession;
/*
* (c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*/
public class EventThread extends Thread {
final MISession session;
final MIEvent[] events;
public EventThread(MISession s, MIEvent[] evts) {
super("MI Event Thread");
session = s;
events = evts;
setDaemon(true);
}
/*
*/
public void run () {
session.notifyObservers(events);
}
}

View file

@ -25,61 +25,38 @@ public class MIDataReadMemoryInfo extends MIInfo {
public MIDataReadMemoryInfo(MIOutput rr) {
super(rr);
parse();
}
public long getAddress() {
if (memories == null) {
parse();
}
return addr;
}
public long getNumberBytes() {
if (memories == null) {
parse();
}
return numBytes;
}
public long getTotalBytes() {
if (memories == null) {
parse();
}
return totalBytes;
}
public long getNextRow() {
if (memories == null) {
parse();
}
return nextRow;
}
public long getPreviousRow() {
if (memories == null) {
parse();
}
return prevRow;
}
public long getNextPage() {
if (memories == null) {
parse();
}
return nextPage;
}
public long getPreviousPage() {
if (memories == null) {
parse();
}
return prevPage;
}
public MIMemory[] getMemories() {
if (memories == null) {
parse();
}
return memories;
}
/*

View file

@ -116,13 +116,13 @@ public class MIParser {
token.delete(0, i);
}
// Process ResultRecord | Out-Of-Band Records
// ResultRecord ||| Out-Of-Band Records
if (token.length() > 0) {
if (token.charAt(0) == '^') {
token.deleteCharAt(0);
rr = processMIResultRecord(token, id);
} else if(token.toString().startsWith(MIOutput.terminator)) {
break;
//break; // Do nothing.
} else {
MIOOBRecord band = processMIOOBRecord(token, id);
if (band != null) {
@ -131,15 +131,14 @@ public class MIParser {
}
}
}
MIOOBRecord[] bands =
(MIOOBRecord[]) oobs.toArray(new MIOOBRecord[oobs.size()]);
MIOOBRecord[] bands = (MIOOBRecord[]) oobs.toArray(new MIOOBRecord[oobs.size()]);
mi.setMIOOBRecords(bands);
mi.setMIResultRecord(rr);
return mi;
}
/**
* Assuming '^' was deleted.
* Assuming '^' was deleted from the Result Record.
*/
private MIResultRecord processMIResultRecord(StringBuffer buffer, int id) {
MIResultRecord rr = new MIResultRecord();
@ -174,6 +173,7 @@ public class MIParser {
}
/**
* Find OutOfBand Records depending on the starting token.
*/
private MIOOBRecord processMIOOBRecord(StringBuffer buffer, int id) {
MIOOBRecord oob = null;
@ -235,7 +235,8 @@ public class MIParser {
}
/**
* Assuming that the usual leading comma was consume.
* Assuming that the usual leading comma was consumed.
* Extract the MI Result comma seperated responses.
*/
private MIResult[] processMIResults(StringBuffer buffer) {
List aList = new ArrayList();
@ -255,7 +256,7 @@ public class MIParser {
/**
* Construct the MIResult. Characters will be consume/delete
* has moving forward constructing the AST.
* moving forward constructing the AST.
*/
private MIResult processMIResult(StringBuffer buffer) {
MIResult result = new MIResult();
@ -353,6 +354,14 @@ public class MIParser {
return list;
}
/*
* MI C-String rather MICOnst values are enclose in double quotes
* and any double quotes or backslash in the string are escaped.
* Assuming the starting double quote was removed.
* This method will stop at the closing double quote remove the extra
* backslach escaping and return the string __without__ the enclosing double quotes
* The orignal StringBuffer will move forward.
*/
private String translateCString(StringBuffer buffer) {
boolean escape = false;
boolean closingQuotes = false;

View file

@ -20,7 +20,7 @@ public class MIStackListArgumentsInfo extends MIInfo {
super(out);
}
public MIFrame[] getFrames() {
public MIFrame[] getMIFrames() {
if (frames == null) {
parse();
}

View file

@ -23,7 +23,7 @@ public class MIStackListFramesInfo extends MIInfo {
if (frames == null) {
parse();
}
return null;
return frames;
}
void parse() {

View file

@ -14,19 +14,14 @@ public class MIThreadSelectInfo extends MIInfo {
public MIThreadSelectInfo(MIOutput out) {
super(out);
parse();
}
public int getNewThreadId() {
if (frame == null) {
parse();
}
return threadId;
}
public MIFrame getFrame() {
if (frame == null) {
parse();
}
return frame;
}

View file

@ -15,7 +15,7 @@ import java.util.List;
*/
public class MIVarListChildrenInfo extends MIInfo {
MIChild[] children = new MIChild[0];
MIChild[] children;
int numchild;
public MIVarListChildrenInfo(MIOutput record) {