15f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes/* 25f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Licensed to the Apache Software Foundation (ASF) under one or more 35f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * contributor license agreements. See the NOTICE file distributed with 45f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * this work for additional information regarding copyright ownership. 55f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * The ASF licenses this file to You under the Apache License, Version 2.0 65f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * (the "License"); you may not use this file except in compliance with 75f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * the License. You may obtain a copy of the License at 85f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 95f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Unless required by applicable law or agreed to in writing, software 125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * See the License for the specific language governing permissions and 165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * limitations under the License. 175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes/** 205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @author Anton V. Karnachuk 215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes/** 245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Created on 16.03.2005 255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughespackage org.apache.harmony.jpda.tests.framework.jdwp; 275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport java.util.List; 295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport java.io.IOException; 305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport java.io.InterruptedIOException; 315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport java.util.ArrayList; 325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport java.util.Enumeration; 335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport java.util.Hashtable; 345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport org.apache.harmony.jpda.tests.framework.LogWriter; 365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport org.apache.harmony.jpda.tests.framework.TestOptions; 375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport org.apache.harmony.jpda.tests.framework.jdwp.exceptions.TimeoutException; 385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes/** 405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * This class provides asynchronous sending JDWP commands and receiving JDWP 415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * events through established JDWP connection and supports timeout for these 425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * operations. 435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughespublic class PacketDispatcher extends Thread { 455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Variables below are intended only to help with tests failures 485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * investigation. They turn on/off some kinds of trace during 495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * tests execution which can clear up details of test failure. 505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * commandsNumberForTrace and begCommandIdForTrace define trace 525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * of sent JDWP commands and received replies for these commands: 535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * - begCommandIdForTrace defines starting command ID for trace 545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * (the first command has ID=1, the second - ID=2 and so on). 555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if <= 0 then the same as = 1. 565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * - commandsNumberForTrace defines number of command for trace. 575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if <= 0 then commands' trace is off. 585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * - eventRequestIDForTrace defines trace of received events 605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * according to request ID value: 615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if < 0 then this trace is off; 625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if = 0 then trace is for all received events; 635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if > 0 then trace is for received events, which are triggered 645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * by this specified request ID value; 655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * - eventKindForTrace defines trace of received events 675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * according to this specified kind of event. 685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if = 0 then this trace is off; 695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * See JDWPConstants.EventKind class for values of 705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * event kinds. 715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int begCommandIdForTrace = 1; 735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int commandsNumberForTrace = 0; 755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int eventRequestIDForTrace = -1; 775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes byte eventKindForTrace = 0; 795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Internal class to synchronize jdwp events. When an event is received it 825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * is stored in eventQueue. If there are any thread that waits for event it 835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * is notified. 845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private class EventsSynchronyzer { 865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * List of received events. 895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private List<EventPacket> eventQueue; 915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * A default constructor. 945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes EventsSynchronyzer() { 965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // initialize eventQueue 975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes eventQueue = new ArrayList<EventPacket>(); 985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 1015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Notifies thread that the new event has been received. 1025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 1035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param eventPacket 1045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * instance of EventPacket 1055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws InterruptedException 1065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 1075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public void notifyThread(EventPacket eventPacket) 1085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throws InterruptedException { 1095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // use this object as lock 1115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (this) { 1125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // add the event to eventQueue 1135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes eventQueue.add(eventPacket); 1145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // notify next waiting thread 1165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes this.notify(); 1175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 1215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Waits for new event during timeout. 1225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 1235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param timeout 1245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * wait timeout 1255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return EventPacket 1265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws InterruptedException 1275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws IOException 1285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws TimeoutException 1295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if no event was received 1305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 1315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public EventPacket waitForNextEvent(long timeout) 1325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throws InterruptedException, IOException { 1335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // use this object as lock 1355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (this) { 1365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if there is already received event in eventQueue, 1385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // then return it 1395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (eventQueue) { 1405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (!eventQueue.isEmpty()) { 1415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return (EventPacket) eventQueue.remove(0); 1425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if eventQueue is empty and connection is already closed 1455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // reraise the exception 1465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) 1475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 1485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // wait for the next event 1515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes this.wait(timeout); 1525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // We have the following opportunities here - 1545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // next event was received, exception in main cyrcle or timeout 1555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // happens 1565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (eventQueue) { 1575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (!eventQueue.isEmpty()) { 1585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // event received 1595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes EventPacket event = (EventPacket) eventQueue.remove(0); 1605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return event; 1615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) { 1645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if eventQueue is empty and connection is already 1655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // closed 1665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // reraise the exception 1675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 1685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // no events were occurred during timeout 1735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw new TimeoutException(false); 1745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 1775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * This method is called when connection is closed. It notifies all the 1785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * waiting threads. 1795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 1805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public void terminate() { 1815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (this) { 1825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes this.notifyAll(); 1835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 1865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 1885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Internal class to synchronize jdwp commands. It sends command packets 1895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * through connection and returns replies. 1905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 1915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes class CommandsSynchronyzer { 1925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private int commandId; 1945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private Hashtable<Integer, CommandPacket> commands; 1965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private Hashtable<Integer, ReplyPacket> replies; 1985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 1995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 2005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * A default constructor. 2015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 2025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes CommandsSynchronyzer() { 2035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes commands = new Hashtable<Integer, CommandPacket>(); 2045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes replies = new Hashtable<Integer, ReplyPacket>(); 2055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // set first command id to 1 2075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes commandId = 1; 2085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 2095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 2115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Gets the next new id for a command. 2125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 2135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return int 2145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 2155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private synchronized int getNextId() { 2165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return commandId++; 2175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 2185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 2205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Notifies thread that reply packet was received. 2215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 2225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param replyPacket 2235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * instance of ReplyPacket 2245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws IOException 2255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws InterruptedException 2265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 2275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public void notifyThread(ReplyPacket replyPacket) throws IOException, 2285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes InterruptedException { 2295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (commands) { 2315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // obtain the current command id 2335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes Integer Id = new Integer(replyPacket.getId()); 2345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // obtain the current command packet by command id 2365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes CommandPacket command = (CommandPacket) commands.remove(Id); 2375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (command == null) { 2385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // we received reply's id that does not correspond to any 2395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // command 2405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw new IOException( 2415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes "Reply id is corresponded to no command. Id = " 2425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + Id); 2435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 2445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (command) { 2465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // put the reply in replies queue 2475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (replies) { 2485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes replies.put(new Integer(replyPacket.getId()), 2495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes replyPacket); 2505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 2515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // notify waiting thread 2525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes command.notifyAll(); 2535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 2545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 2555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 2565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 2585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Sends command and waits for the reply during timeout. 2595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 2605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param command 2615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * instance of CommandPacket 2625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param timeout 2635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * reply wait timeout 2645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return 2655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws TimeoutException 2665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if no reply was received 2675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 2685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public ReplyPacket waitForReply(CommandPacket command, long timeout) 2695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throws InterruptedException, IOException { 2705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (command) { 2725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if connection is already closed reraise the exception 2745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) 2755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 2765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // obtain new command id 2785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes Integer Id = new Integer(getNextId()); 2795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes command.setId(Id.intValue()); 2805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // add command into commands hashtable 2825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (commands) { 2835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes commands.put(Id, command); 2845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 2855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // below is trace for sent coomasnds 2865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (commandsNumberForTrace > 0) { 2875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int begCommandId = begCommandIdForTrace > 1 ? begCommandIdForTrace 2885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes : 1; 2895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (Id.intValue() >= begCommandId) { 2905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if ((Id.intValue() - begCommandId) < commandsNumberForTrace) { 2915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes logWriter 2925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .println(">>>>>>>>>> PacketDispatcher: PERFORM command: ID = " 2935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + Id.intValue() 2945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + "; CommandSet = " 2955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + command.getCommandSet() 2965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + "; Command = " 2975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + command.getCommand() + "..."); 2985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 2995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // write this package to connection 3035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes connection.writePacket(command.toBytesArray()); 3045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if connection is already closed reraise the exception 3075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) 3085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 3095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // wait for reply 3115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes command.wait(timeout); 3125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // receive the reply 3145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes ReplyPacket currentReply = null; 3155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (replies) { 3165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes currentReply = (ReplyPacket) replies.remove(Id); 3175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if reply is ok, return it 3205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (currentReply != null) { 3215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return currentReply; 3225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if connection is already closed reraise the exception 3255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) 3265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 3275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // no event was occurred during timeout 3305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw new TimeoutException(false); 3315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 3345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Sends command without waiting for the reply and returns id of the 3355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * sent command. 3365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 3375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param command 3385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * instance of CommandPacket 3395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return command id 3405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws IOException 3415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 3425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public int sendCommand(CommandPacket command) throws IOException { 3435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if connection is already closed reraise the exception 3455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) 3465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 3475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // obtain new command id 3495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes Integer Id = new Integer(getNextId()); 3505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes command.setId(Id.intValue()); 3515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // add command into commands hashtable 3535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (commands) { 3545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes commands.put(Id, command); 3555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // below is trace for sent coomasnds 3575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (commandsNumberForTrace > 0) { 3585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int begCommandId = begCommandIdForTrace > 1 ? begCommandIdForTrace 3595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes : 1; 3605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (Id.intValue() >= begCommandId) { 3615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if ((Id.intValue() - begCommandId) < commandsNumberForTrace) { 3625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes logWriter 3635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .println(">>>>>>>>>> PacketDispatcher: PERFORM command: ID = " 3645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + Id.intValue() 3655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + "; CommandSet = " 3665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + command.getCommandSet() 3675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + "; Command = " 3685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + command.getCommand() + "..."); 3695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // write this package to connection 3745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes connection.writePacket(command.toBytesArray()); 3755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if connection is already closed reraise the exception 3785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) { 3795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 3805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return Id.intValue(); 3835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 3855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 3865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 3875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Receives the reply during timeout for command with specified command 3885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * ID. 3895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 3905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param commandId 3915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * id of previously sent commend 3925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param timeout 3935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * receive timeout 3945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return received ReplyPacket 3955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws TimeoutException 3965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if no reply was received 3975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 3985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public ReplyPacket receiveReply(int commandId, long timeout) 3995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throws InterruptedException, IOException { 4005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if connection is already closed reraise the exception 4025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) 4035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 4045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // receive the reply 4065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes ReplyPacket currentReply = null; 4075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes long endTimeMlsecForWait = System.currentTimeMillis() + timeout; 4085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (replies) { 4095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes while (true) { 4105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes currentReply = (ReplyPacket) replies.remove(new Integer( 4115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes commandId)); 4125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if reply is ok, return it 4135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (currentReply != null) { 4145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return currentReply; 4155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // if connection is already closed reraise the exception 4175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (connectionException != null) { 4185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw connectionException; 4195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (System.currentTimeMillis() >= endTimeMlsecForWait) { 4215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes break; 4225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes replies.wait(100); 4245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // no expected reply was found during timeout 4275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throw new TimeoutException(false); 4285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 4315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * This method is called when connection is closed. It notifies all the 4325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * waiting threads. 4335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 4345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 4355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public void terminate() { 4365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (commands) { 4385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // enumerate all waiting commands 4395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes for (Enumeration en = commands.keys(); en.hasMoreElements();) { 4405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes CommandPacket command = (CommandPacket) commands.get(en 4415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .nextElement()); 4425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes synchronized (command) { 4435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // notify the waiting object 4445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes command.notifyAll(); 4455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** Transport which is used to sent and receive packets. */ 4525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private TransportWrapper connection; 4535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** Current test run configuration. */ 4555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes TestOptions config; 4565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private CommandsSynchronyzer commandsSynchronyzer; 4585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private EventsSynchronyzer eventsSynchronyzer; 4605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private LogWriter logWriter; 4625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes private IOException connectionException; 4645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 4665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Creates new PacketDispatcher instance. 4675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 4685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param connection 4695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * open connection for reading and writing packets 4705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param config 4715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * test run options 4725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param logWriter 4735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * LogWriter object 4745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 4755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public PacketDispatcher(TransportWrapper connection, TestOptions config, 4765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes LogWriter logWriter) { 4775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes this.connection = connection; 4795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes this.config = config; 4805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes this.logWriter = logWriter; 4815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes commandsSynchronyzer = new CommandsSynchronyzer(); 4835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes eventsSynchronyzer = new EventsSynchronyzer(); 4845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // make thread daemon 4865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes setDaemon(true); 4875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // start the thread 4895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes start(); 4905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 4915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 4935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Reads packets from connection and dispatches them between waiting 4945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * threads. 4955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 4965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public void run() { 4975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 4985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes connectionException = null; 4995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes try { 5015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // start listening for replies 5025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes while (!isInterrupted()) { 5035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // read packet from transport 5055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes byte[] packet = connection.readPacket(); 5065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // break cycle if empty packet 5085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (packet == null || packet.length == 0) 5095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes break; 5105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // check flags 5125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (packet.length < Packet.FLAGS_INDEX) { 5135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes logWriter 5145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .println(">>>>>>>>>> PacketDispatcher WARNING: WRONG received packet size = " 5155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + packet.length); 5165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } else { 5175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int flag = packet[Packet.FLAGS_INDEX] & 0xFF; 5185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (flag != 0) { 5195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (flag != Packet.REPLY_PACKET_FLAG) { 5205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes logWriter 5215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .println(">>>>>>>>>> PacketDispatcher WARNING: WRONG received packet flags = " 5225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + Integer.toHexString(flag)); 5235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // check the reply flag 5285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (Packet.isReply(packet)) { 5295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // new reply 5305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes ReplyPacket replyPacket = new ReplyPacket(packet); 5315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // check for received reply packet length 5335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int packetLength = replyPacket.getLength(); 5345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (packetLength < Packet.HEADER_SIZE) { 5355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes logWriter 5365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .println(">>>>>>>>>> PacketDispatcher WARNING: WRONG received packet length = " 5375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + packetLength); 5385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // below is trace for received coomasnds 5415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (commandsNumberForTrace > 0) { 5425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int replyID = replyPacket.getId(); 5435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int begCommandId = begCommandIdForTrace > 1 ? begCommandIdForTrace 5445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes : 1; 5455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (replyID >= begCommandId) { 5465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if ((replyID - begCommandId) < commandsNumberForTrace) { 5475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes logWriter 5485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .println(">>>>>>>>>> PacketDispatcher: Received REPLY ID = " 5495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + replyID); 5505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes commandsSynchronyzer.notifyThread(replyPacket); 5555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } else { 5565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // new event 5575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes EventPacket eventPacket = new EventPacket(packet); 5585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // below is to check received events for correctness 5595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // below is trace for received events 5615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes ParsedEvent[] parsedEvents = ParsedEvent 5625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .parseEventPacket(eventPacket); 5635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if ((eventRequestIDForTrace >= 0) 5645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes || (eventKindForTrace > 0)) { 5655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes for (int i = 0; i < parsedEvents.length; i++) { 5665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes boolean trace = false; 5675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes int eventRequestID = parsedEvents[i].getRequestID(); 5685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (eventRequestIDForTrace == 0) { 5695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes trace = true; 5705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } else { 5715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (eventRequestID == eventRequestIDForTrace) { 5725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes trace = true; 5735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes byte eventKind = parsedEvents[i].getEventKind(); 5765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (eventKind == eventKindForTrace) { 5775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes trace = true; 5785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes if (trace) { 5805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes logWriter 5815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .println(">>>>>>>>>> PacketDispatcher: Received_EVENT[" 5825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + i 5835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + "]: eventRequestID= " 5845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + eventRequestID 5855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + "; eventKind = " 5865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + eventKind 5875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + "(" 5885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + JDWPConstants.EventKind 5895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes .getName(eventKind) 5905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes + ")"); 5915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes eventsSynchronyzer.notifyThread(eventPacket); 5955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 5975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 5985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // this exception is send for all waiting threads 5995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes connectionException = new TimeoutException(true); 6005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } catch (IOException e) { 6015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // connection exception is send for all waiting threads 6025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes connectionException = e; 6035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // print stack trace 6055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes e.printStackTrace(); 6065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } catch (InterruptedException e) { 6075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // connection exception is send for all waiting threads 6085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes connectionException = new InterruptedIOException(e.getMessage()); 6095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes connectionException.initCause(e); 6105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // print stack trace 6125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes e.printStackTrace(); 6135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 6145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes // notify all the waiting threads 6165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes eventsSynchronyzer.terminate(); 6175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes commandsSynchronyzer.terminate(); 6185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 6195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 6215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Receives event from event queue if there are any events or waits during 6225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * timeout for any event occurrence. This method should not be used 6235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * simultaneously from different threads. If there were no reply during the 6245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * timeout, TimeoutException is thrown. 6255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 6265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param timeout 6275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * timeout in milliseconds 6285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return received event packet 6295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws IOException 6305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * is any connection error occurred 6315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws InterruptedException 6325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if reading packet was interrupted 6335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws TimeoutException 6345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if timeout exceeded 6355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 6365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public EventPacket receiveEvent(long timeout) throws IOException, 6375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes InterruptedException, TimeoutException { 6385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return eventsSynchronyzer.waitForNextEvent(timeout); 6405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 6415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 6435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Sends JDWP command packet and waits for reply packet during default 6445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * timeout. If there were no reply packet during the timeout, 6455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * TimeoutException is thrown. 6465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 6475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return received reply packet 6485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws InterruptedException 6495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if reading packet was interrupted 6505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws IOException 6515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if any connection error occurred 6525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws TimeoutException 6535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if timeout exceeded 6545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 6555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public ReplyPacket performCommand(CommandPacket command) 6565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throws InterruptedException, IOException, TimeoutException { 6575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return performCommand(command, config.getTimeout()); 6595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 6605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 6625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Sends JDWP command packet and waits for reply packet during certain 6635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * timeout. If there were no reply packet during the timeout, 6645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * TimeoutException is thrown. 6655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 6665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param command 6675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * command packet to send 6685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param timeout 6695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * timeout in milliseconds 6705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return received reply packet 6715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws InterruptedException 6725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if packet reading was interrupted 6735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws IOException 6745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if any connection error occurred 6755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws TimeoutException 6765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if timeout exceeded 6775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 6785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public ReplyPacket performCommand(CommandPacket command, long timeout) 6795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throws InterruptedException, IOException, TimeoutException { 6805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return commandsSynchronyzer.waitForReply(command, timeout); 6825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 6835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 6845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 6855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Sends CommandPacket to debuggee VM without waiting for the reply. This 6865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * method is intended for special cases when there is need to divide 6875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * command's performing into two actions: command's sending and receiving 6885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * reply (e.g. for asynchronous JDWP commands' testing). After this method 6895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * the 'receiveReply()' method must be used latter for receiving reply for 6905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * sent command. It is NOT recommended to use this method for usual cases - 6915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 'performCommand()' method must be used. 6925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 6935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param command 6945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Command packet to be sent 6955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return command ID of sent command 6965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws IOException 6975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if any connection error occurred 6985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 6995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public int sendCommand(CommandPacket command) throws IOException { 7005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return commandsSynchronyzer.sendCommand(command); 7015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 7025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 7035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes /** 7045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Waits for reply for command which was sent before by 'sendCommand()' 7055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * method. Specified timeout is used as time limit for waiting. This method 7065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * (jointly with 'sendCommand()') is intended for special cases when there 7075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * is need to divide command's performing into two actions: command's 7085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * sending and receiving reply (e.g. for asynchronous JDWP commands' 7095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * testing). It is NOT recommended to use 'sendCommand()- receiveReply()' 7105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * pair for usual cases - 'performCommand()' method must be used. 7115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * 7125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param commandId 7135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Command ID of sent before command, reply from which is 7145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * expected to be received 7155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @param timeout 7165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Specified timeout in milliseconds to wait for reply 7175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @return received ReplyPacket 7185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws IOException 7195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if any connection error occurred 7205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws InterruptedException 7215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if reply packet's waiting was interrupted 7225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @throws TimeoutException 7235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * if timeout exceeded 7245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */ 7255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes public ReplyPacket receiveReply(int commandId, long timeout) 7265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes throws InterruptedException, IOException, TimeoutException { 7275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes return commandsSynchronyzer.receiveReply(commandId, timeout); 7285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes } 7295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes 7305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes} 731