blob: 0c4d5426b9396f9b7ca7082a98e0cfa5b0b08403 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 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
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdi.internal.connect;
import java.io.IOException;
import java.io.InterruptedIOException;
import com.ibm.icu.text.MessageFormat;
import java.util.LinkedList;
import org.eclipse.jdi.internal.jdwp.JdwpPacket;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.connect.spi.Connection;
/**
* This class implements a thread that sends available packets to the Virtual Machine.
*
*/
public class PacketSendManager extends PacketManager {
/** List of packets to be sent to Virtual Machine */
private LinkedList fOutgoingPackets;
/**
* Create a new thread that send packets to the Virtual Machine.
*/
public PacketSendManager(Connection connection) {
super(connection);
fOutgoingPackets = new LinkedList();
}
public void disconnectVM() {
super.disconnectVM();
synchronized (fOutgoingPackets) {
fOutgoingPackets.notifyAll();
}
}
/**
* Thread's run method.
*/
public void run() {
while (!VMIsDisconnected()) {
try {
sendAvailablePackets();
}
//in each case if the remote VM fails, or has been interrupted, disconnect and force a clean up, don't wait for it to happen
catch (InterruptedException e) {disconnectVM();}
catch (InterruptedIOException e) {disconnectVM(e);}
catch (IOException e) {disconnectVM(e);}
}
}
/**
* Add a packet to be sent to the Virtual Machine.
*/
public void sendPacket(JdwpPacket packet) {
if (VMIsDisconnected()) {
String message;
if (getDisconnectException() == null) {
message= ConnectMessages.PacketSendManager_Got_IOException_from_Virtual_Machine_1;
}
else {
String exMessage = getDisconnectException().getMessage();
if (exMessage == null) {
message= MessageFormat.format(ConnectMessages.PacketSendManager_Got__0__from_Virtual_Machine_1, new String[] {getDisconnectException().getClass().getName()});
}
else {
message= MessageFormat.format(ConnectMessages.PacketSendManager_Got__0__from_Virtual_Machine___1__1, new String[] {getDisconnectException().getClass().getName(), exMessage});
}
}
throw new VMDisconnectedException(message);
}
synchronized(fOutgoingPackets) {
// Add packet to list of packets to send.
fOutgoingPackets.add(packet);
// Notify PacketSendThread that data is available.
fOutgoingPackets.notifyAll();
}
}
/**
* Send available packets to the Virtual Machine.
*/
private void sendAvailablePackets() throws InterruptedException, IOException {
LinkedList packetsToSend = new LinkedList();
synchronized (fOutgoingPackets) {
while (fOutgoingPackets.size() == 0) {
fOutgoingPackets.wait();
}
packetsToSend.addAll(fOutgoingPackets);
fOutgoingPackets.clear();
}
// Put available packets on Output Stream.
while (packetsToSend.size() > 0) {
// Note that only JdwpPackets are added to the list, so a ClassCastException can't occur.
JdwpPacket packet = (JdwpPacket)packetsToSend.removeFirst();
byte[] bytes = packet.getPacketAsBytes();
getConnection().writePacket(bytes);
}
}
}