001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdi.internal.connect;
011:
012: import java.io.IOException;
013: import java.io.InterruptedIOException;
014: import com.ibm.icu.text.MessageFormat;
015: import java.util.LinkedList;
016:
017: import org.eclipse.jdi.internal.jdwp.JdwpPacket;
018:
019: import com.sun.jdi.VMDisconnectedException;
020: import com.sun.jdi.connect.spi.Connection;
021:
022: /**
023: * This class implements a thread that sends available packets to the Virtual Machine.
024: *
025: */
026: public class PacketSendManager extends PacketManager {
027: /** List of packets to be sent to Virtual Machine */
028: private LinkedList fOutgoingPackets;
029:
030: /**
031: * Create a new thread that send packets to the Virtual Machine.
032: */
033: public PacketSendManager(Connection connection) {
034: super (connection);
035: fOutgoingPackets = new LinkedList();
036: }
037:
038: public void disconnectVM() {
039: super .disconnectVM();
040: synchronized (fOutgoingPackets) {
041: fOutgoingPackets.notifyAll();
042: }
043: }
044:
045: /**
046: * Thread's run method.
047: */
048: public void run() {
049: while (!VMIsDisconnected()) {
050: try {
051: sendAvailablePackets();
052: }
053: //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
054: catch (InterruptedException e) {
055: disconnectVM();
056: } catch (InterruptedIOException e) {
057: disconnectVM(e);
058: } catch (IOException e) {
059: disconnectVM(e);
060: }
061: }
062: }
063:
064: /**
065: * Add a packet to be sent to the Virtual Machine.
066: */
067: public void sendPacket(JdwpPacket packet) {
068: if (VMIsDisconnected()) {
069: String message;
070: if (getDisconnectException() == null) {
071: message = ConnectMessages.PacketSendManager_Got_IOException_from_Virtual_Machine_1;
072: } else {
073: String exMessage = getDisconnectException()
074: .getMessage();
075: if (exMessage == null) {
076: message = MessageFormat
077: .format(
078: ConnectMessages.PacketSendManager_Got__0__from_Virtual_Machine_1,
079: new String[] { getDisconnectException()
080: .getClass().getName() });
081: } else {
082: message = MessageFormat
083: .format(
084: ConnectMessages.PacketSendManager_Got__0__from_Virtual_Machine___1__1,
085: new String[] {
086: getDisconnectException()
087: .getClass()
088: .getName(),
089: exMessage });
090: }
091: }
092: throw new VMDisconnectedException(message);
093: }
094:
095: synchronized (fOutgoingPackets) {
096: // Add packet to list of packets to send.
097: fOutgoingPackets.add(packet);
098: // Notify PacketSendThread that data is available.
099: fOutgoingPackets.notifyAll();
100: }
101: }
102:
103: /**
104: * Send available packets to the Virtual Machine.
105: */
106: private void sendAvailablePackets() throws InterruptedException,
107: IOException {
108: LinkedList packetsToSend = new LinkedList();
109: synchronized (fOutgoingPackets) {
110: while (fOutgoingPackets.size() == 0) {
111: fOutgoingPackets.wait();
112: }
113: packetsToSend.addAll(fOutgoingPackets);
114: fOutgoingPackets.clear();
115: }
116:
117: // Put available packets on Output Stream.
118: while (packetsToSend.size() > 0) {
119: // Note that only JdwpPackets are added to the list, so a ClassCastException can't occur.
120: JdwpPacket packet = (JdwpPacket) packetsToSend
121: .removeFirst();
122: byte[] bytes = packet.getPacketAsBytes();
123: getConnection().writePacket(bytes);
124: }
125: }
126: }
|