blob: 89ff2e8339397a2544e462becc47abd35ff43038 [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.proxy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.ptp.core.proxy.AbstractProxyClient;
import org.eclipse.ptp.core.proxy.event.IProxyConnectedEvent;
import org.eclipse.ptp.core.proxy.event.IProxyDisconnectedEvent;
import org.eclipse.ptp.core.proxy.event.IProxyMessageEvent;
import org.eclipse.ptp.core.proxy.event.IProxyEventListener;
import org.eclipse.ptp.core.proxy.event.IProxyExtendedEvent;
import org.eclipse.ptp.core.proxy.event.IProxyOKEvent;
import org.eclipse.ptp.core.proxy.event.IProxyTimeoutEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugArgsEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugBreakpointHitEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugBreakpointSetEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugDataEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugDataExpValueEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugErrorEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugEventListener;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugExitEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugInfoThreadsEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugInitEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugMemoryInfoEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugOKEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugPartialAIFEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugSetThreadSelectEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugSignalEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugSignalExitEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugSignalsEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugStackInfoDepthEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugStackframeEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugStepEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugSuspendEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugTypeEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugVarsEvent;
import org.eclipse.ptp.debug.external.core.proxy.event.ProxyDebugEventFactory;
public abstract class AbstractProxyDebugClient extends AbstractProxyClient implements IProxyDebugClient,IProxyEventListener {
private List<IProxyDebugEventListener> listeners =
Collections.synchronizedList(new ArrayList<IProxyDebugEventListener>());
private boolean waiting = false;
private boolean timeout = false;
private final ReentrantLock waitLock = new ReentrantLock();
private final Condition waitCondition = waitLock.newCondition();
private volatile DebugProxyState state;
protected enum DebugProxyState {
DISCONNECTED,
DISCONNECTING,
CONNECTED,
CONNECTING
}
public AbstractProxyDebugClient() {
super(new ProxyDebugEventFactory());
super.addProxyEventListener(this);
state = DebugProxyState.DISCONNECTED;
}
public void finalize() {
super.removeProxyEventListener(this);
}
/**
* Create the debugger connection.
*
* @throws IOException
*/
public void doConnect(int timeout) throws IOException {
sessionCreate(timeout);
state = DebugProxyState.CONNECTING;
}
/**
* Wait for the debugger to connect. We will receive a connected event
* when the debug server actually connects, or a timeout event if the server
* fails to connect. If the user cancels the wait, we call doShutdown() to
* terminate the debugger connection.
*
* @param monitor
* @return true on successful connection, false otherwise
* @throws IOException
*/
public boolean waitConnect(IProgressMonitor monitor) throws IOException {
System.out.println("debug: waiting for connect");
if (monitor == null) {
monitor = new NullProgressMonitor();
}
waitLock.lock();
try {
if (state == DebugProxyState.CONNECTING) {
while (state != DebugProxyState.CONNECTED && !timeout && !monitor.isCanceled()) {
waiting = true;
try {
waitCondition.await();
} catch (InterruptedException e) {
// Expect to be interrupted if monitor is canceled
}
}
if (timeout) {
throw new IOException("Timeout waiting for debugger to connect");
} else if (monitor.isCanceled()) {
doShutdown();
return false;
}
}
return true;
} finally {
waitLock.unlock();
monitor.done();
}
}
/**
* Shutdown the debugger connection. This can be called if we are either in the CONNECTED
* state, in which case we will receive a disconnected event, or in the CONNECTING state,
* in which case we will receive an error event.
*
* @throws IOException
*/
public void doShutdown() throws IOException {
waitLock.lock();
try {
if (state == DebugProxyState.CONNECTING || state == DebugProxyState.CONNECTED) {
state = DebugProxyState.DISCONNECTING;
System.out.println("calling session finish");
sessionFinish();
while (state == DebugProxyState.DISCONNECTING) {
waiting = true;
try {
waitCondition.await(30000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
}
}
}
} finally {
waitLock.unlock();
state = DebugProxyState.DISCONNECTED;
}
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.external.core.proxy.IProxyDebugClient#addProxyDebugEventListener(org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugEventListener)
*/
public void addProxyDebugEventListener(IProxyDebugEventListener listener) {
listeners.add(listener);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.external.core.proxy.IProxyDebugClient#removeProxyDebugEventListener(org.eclipse.ptp.debug.external.core.proxy.event.IProxyDebugEventListener)
*/
public void removeProxyDebugEventListener(IProxyDebugEventListener listener) {
listeners.remove(listener);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.core.proxy.event.IProxyEventListener#handleProxyConnectedEvent(org.eclipse.ptp.core.proxy.event.IProxyConnectedEvent)
*/
public void handleProxyConnectedEvent(IProxyConnectedEvent e) {
System.out.println("debug: received connected event");
waitLock.lock();
try {
state = DebugProxyState.CONNECTED;
if (waiting) {
waitCondition.signal();
waiting = false;
}
} finally {
waitLock.unlock();
}
}
/* (non-Javadoc)
* @see org.eclipse.ptp.core.proxy.event.IProxyEventListener#handleProxyDisconnectedEvent(org.eclipse.ptp.core.proxy.event.IProxyDisconnectedEvent)
*/
public void handleProxyDisconnectedEvent(IProxyDisconnectedEvent e) {
System.out.println("debug: received disconnected event");
waitLock.lock();
try {
if (state == DebugProxyState.DISCONNECTING) {
state = DebugProxyState.DISCONNECTED;
if (waiting) {
waitCondition.signal();
waiting = false;
}
}
} finally {
waitLock.unlock();
}
}
/* (non-Javadoc)
* @see org.eclipse.ptp.core.proxy.event.IProxyEventListener#handleProxyErrorEvent(org.eclipse.ptp.core.proxy.event.IProxyErrorEvent)
*/
public void handleProxyMessageEvent(IProxyMessageEvent e) {
System.out.println("debug: received error event");
waitLock.lock();
try {
if (state == DebugProxyState.DISCONNECTING) {
state = DebugProxyState.DISCONNECTED;
if (waiting) {
waitCondition.signal();
waiting = false;
}
}
} finally {
waitLock.unlock();
}
}
/* (non-Javadoc)
* @see org.eclipse.ptp.core.proxy.event.IProxyEventListener#handleProxyOKEvent(org.eclipse.ptp.core.proxy.event.IProxyOKEvent)
*/
public void handleProxyOKEvent(IProxyOKEvent e) {
System.out.println("debug: received ok event");
}
/* (non-Javadoc)
* @see org.eclipse.ptp.core.proxy.event.IProxyEventListener#handleProxyTimeoutEvent(org.eclipse.ptp.core.proxy.event.IProxyTimeoutEvent)
*/
public void handleProxyTimeoutEvent(IProxyTimeoutEvent e) {
System.out.println("debug: received timeout event");
waitLock.lock();
try {
timeout = true;
if (waiting) {
waitCondition.signal();
waiting = false;
}
} finally {
waitLock.unlock();
}
}
public void handleProxyExtendedEvent(IProxyExtendedEvent e) {
if (e instanceof IProxyDebugArgsEvent) {
fireProxyDebugArgsEvent((IProxyDebugArgsEvent) e);
} else if (e instanceof IProxyDebugBreakpointHitEvent) {
fireProxyDebugBreakpointHitEvent((IProxyDebugBreakpointHitEvent) e);
} else if (e instanceof IProxyDebugBreakpointSetEvent) {
fireProxyDebugBreakpointSetEvent((IProxyDebugBreakpointSetEvent) e);
} else if (e instanceof IProxyDebugDataEvent) {
fireProxyDebugDataEvent((IProxyDebugDataEvent) e);
} else if (e instanceof IProxyDebugDataExpValueEvent) {
fireProxyDebugDataExpValueEvent((IProxyDebugDataExpValueEvent) e);
} else if (e instanceof IProxyDebugExitEvent) {
fireProxyDebugExitEvent((IProxyDebugExitEvent) e);
} else if (e instanceof IProxyDebugErrorEvent) {
fireProxyDebugErrorEvent((IProxyDebugErrorEvent) e);
} else if (e instanceof IProxyDebugInfoThreadsEvent) {
fireProxyDebugInfoThreadsEvent((IProxyDebugInfoThreadsEvent) e);
} else if (e instanceof IProxyDebugInitEvent) {
fireProxyDebugInitEvent((IProxyDebugInitEvent) e);
} else if (e instanceof IProxyDebugMemoryInfoEvent) {
fireProxyDebugMemoryInfoEvent((IProxyDebugMemoryInfoEvent) e);
} else if (e instanceof IProxyDebugOKEvent) {
fireProxyDebugOKEvent((IProxyDebugOKEvent) e);
} else if (e instanceof IProxyDebugPartialAIFEvent) {
fireProxyDebugPartialAIFEvent((IProxyDebugPartialAIFEvent) e);
} else if (e instanceof IProxyDebugSetThreadSelectEvent) {
fireProxyDebugSetThreadSelectEvent((IProxyDebugSetThreadSelectEvent) e);
} else if (e instanceof IProxyDebugSignalEvent) {
fireProxyDebugSignalEvent((IProxyDebugSignalEvent) e);
} else if (e instanceof IProxyDebugSignalExitEvent) {
fireProxyDebugSignalExitEvent((IProxyDebugSignalExitEvent) e);
} else if (e instanceof IProxyDebugSignalsEvent) {
fireProxyDebugSignalsEvent((IProxyDebugSignalsEvent) e);
} else if (e instanceof IProxyDebugStackframeEvent) {
fireProxyDebugStackframeEvent((IProxyDebugStackframeEvent) e);
} else if (e instanceof IProxyDebugStackInfoDepthEvent) {
fireProxyDebugStackInfoDepthEvent((IProxyDebugStackInfoDepthEvent) e);
} else if (e instanceof IProxyDebugStepEvent) {
fireProxyDebugStepEvent((IProxyDebugStepEvent) e);
} else if (e instanceof IProxyDebugSuspendEvent) {
fireProxyDebugSuspendEvent((IProxyDebugSuspendEvent) e);
} else if (e instanceof IProxyDebugTypeEvent) {
fireProxyDebugTypeEvent((IProxyDebugTypeEvent) e);
} else if (e instanceof IProxyDebugVarsEvent) {
fireProxyDebugVarsEvent((IProxyDebugVarsEvent) e);
}
}
protected void fireProxyDebugArgsEvent(IProxyDebugArgsEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugArgsEvent(e);
}
}
protected void fireProxyDebugBreakpointHitEvent(IProxyDebugBreakpointHitEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugBreakpointHitEvent(e);
}
}
protected void fireProxyDebugBreakpointSetEvent(IProxyDebugBreakpointSetEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugBreakpointSetEvent(e);
}
}
protected void fireProxyDebugDataEvent(IProxyDebugDataEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugDataEvent(e);
}
}
protected void fireProxyDebugDataExpValueEvent(IProxyDebugDataExpValueEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugDataExpValueEvent(e);
}
}
protected void fireProxyDebugExitEvent(IProxyDebugExitEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugExitEvent(e);
}
}
protected void fireProxyDebugErrorEvent(IProxyDebugErrorEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugErrorEvent(e);
}
}
protected void fireProxyDebugInfoThreadsEvent(IProxyDebugInfoThreadsEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugInfoThreadsEvent(e);
}
}
protected void fireProxyDebugInitEvent(IProxyDebugInitEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugInitEvent(e);
}
}
protected void fireProxyDebugMemoryInfoEvent(IProxyDebugMemoryInfoEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugMemoryInfoEvent(e);
}
}
protected void fireProxyDebugOKEvent(IProxyDebugOKEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugOKEvent(e);
}
}
protected void fireProxyDebugPartialAIFEvent(IProxyDebugPartialAIFEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugPartialAIFEvent(e);
}
}
protected void fireProxyDebugSetThreadSelectEvent(IProxyDebugSetThreadSelectEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugSetThreadSelectEvent(e);
}
}
protected void fireProxyDebugSignalEvent(IProxyDebugSignalEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugSignalEvent(e);
}
}
protected void fireProxyDebugSignalExitEvent(IProxyDebugSignalExitEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugSignalExitEvent(e);
}
}
protected void fireProxyDebugSignalsEvent(IProxyDebugSignalsEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugSignalsEvent(e);
}
}
protected void fireProxyDebugStackframeEvent(IProxyDebugStackframeEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugStackframeEvent(e);
}
}
protected void fireProxyDebugStackInfoDepthEvent(IProxyDebugStackInfoDepthEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugStackInfoDepthEvent(e);
}
}
protected void fireProxyDebugStepEvent(IProxyDebugStepEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugStepEvent(e);
}
}
protected void fireProxyDebugSuspendEvent(IProxyDebugSuspendEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugSuspendEvent(e);
}
}
protected void fireProxyDebugTypeEvent(IProxyDebugTypeEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugTypeEvent(e);
}
}
protected void fireProxyDebugVarsEvent(IProxyDebugVarsEvent e) {
IProxyDebugEventListener[] la = listeners.toArray(new IProxyDebugEventListener[0]);
for (IProxyDebugEventListener listener : la) {
listener.handleProxyDebugVarsEvent(e);
}
}
}