blob: 904b1191a08db37bd518332c1e998b5ac4e7f30d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2017 IBM Corporation 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
*
*******************************************************************************/
package org.eclipse.dltk.dbgp.internal;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.Socket;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.dbgp.DbgpRequest;
import org.eclipse.dltk.dbgp.IDbgpRawListener;
import org.eclipse.dltk.dbgp.IDbgpRawPacket;
import org.eclipse.dltk.dbgp.internal.packets.DbgpNotifyPacket;
import org.eclipse.dltk.dbgp.internal.packets.DbgpPacketReceiver;
import org.eclipse.dltk.dbgp.internal.packets.DbgpPacketSender;
import org.eclipse.dltk.dbgp.internal.packets.DbgpResponsePacket;
import org.eclipse.dltk.dbgp.internal.packets.DbgpStreamPacket;
import org.eclipse.dltk.debug.core.ExtendedDebugEventDetails;
import org.eclipse.dltk.internal.debug.core.model.DebugEventHelper;
public class DbgpDebugingEngine extends DbgpTermination
implements IDbgpDebugingEngine, IDbgpTerminationListener {
private final Socket socket;
private final DbgpPacketReceiver receiver;
private final DbgpPacketSender sender;
private final Object terminatedLock = new Object();
private boolean terminated = false;
private final int id;
private static int lastId = 0;
private static final Object idLock = new Object();
public DbgpDebugingEngine(Socket socket) throws IOException {
this.socket = socket;
synchronized (idLock) {
id = ++lastId;
}
receiver = new DbgpPacketReceiver(
new BufferedInputStream(socket.getInputStream()));
receiver.setLogger(output -> firePacketReceived(output));
receiver.addTerminationListener(this);
receiver.start();
sender = new DbgpPacketSender(
new BufferedOutputStream(socket.getOutputStream()));
sender.setLogger(output -> firePacketSent(output));
/*
* FIXME this event is delivered on the separate thread, so sometimes
* logging misses a few initial packets.
*/
DebugEventHelper.fireExtendedEvent(this,
ExtendedDebugEventDetails.DGBP_NEW_CONNECTION);
}
@Override
public DbgpStreamPacket getStreamPacket()
throws IOException, InterruptedException {
return receiver.getStreamPacket();
}
@Override
public DbgpNotifyPacket getNotifyPacket()
throws IOException, InterruptedException {
return receiver.getNotifyPacket();
}
@Override
public DbgpResponsePacket getResponsePacket(int transactionId, int timeout)
throws IOException, InterruptedException {
return receiver.getResponsePacket(transactionId, timeout);
}
@Override
public void sendCommand(DbgpRequest command) throws IOException {
sender.sendCommand(command);
}
// IDbgpTerminataion
@Override
public void requestTermination() {
// always just close the socket
try {
socket.close();
} catch (IOException e) {
if (DLTKCore.DEBUG) {
e.printStackTrace();
}
}
}
@Override
public void waitTerminated() throws InterruptedException {
synchronized (terminatedLock) {
if (terminated) {
return;
}
receiver.waitTerminated();
}
}
@Override
public void objectTerminated(Object object, Exception e) {
synchronized (terminatedLock) {
if (terminated)
return;
receiver.removeTerminationListener(this);
try {
receiver.waitTerminated();
} catch (InterruptedException e1) {
// OK, interrupted
}
terminated = true;
}
fireObjectTerminated(e);
}
private final ListenerList listeners = new ListenerList();
protected void firePacketReceived(IDbgpRawPacket content) {
Object[] list = listeners.getListeners();
for (int i = 0; i < list.length; ++i) {
((IDbgpRawListener) list[i]).dbgpPacketReceived(id, content);
}
}
protected void firePacketSent(IDbgpRawPacket content) {
Object[] list = listeners.getListeners();
for (int i = 0; i < list.length; ++i) {
((IDbgpRawListener) list[i]).dbgpPacketSent(id, content);
}
}
@Override
public void addRawListener(IDbgpRawListener listener) {
listeners.add(listener);
}
@Override
public void removeRawListenr(IDbgpRawListener listener) {
listeners.remove(listener);
}
}