test/hotspot/jtreg/vmTestbase/nsk/share/jpda/SocketConnection.java
changeset 49934 44839fbb20db
equal deleted inserted replaced
49933:c63bdf53a1a7 49934:44839fbb20db
       
     1 /*
       
     2  * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 package nsk.share.jpda;
       
    25 
       
    26 import java.io.*;
       
    27 import java.net.*;
       
    28 
       
    29 import nsk.share.*;
       
    30 
       
    31 /**
       
    32  * This class implements basic connection channel via TCP/IP sockets.
       
    33  */
       
    34 class BasicSocketConnection {
       
    35 
       
    36     protected static int TRACE_LEVEL_PACKETS = 10;
       
    37 
       
    38     protected static int TRACE_LEVEL_THREADS = 20;
       
    39 
       
    40     protected static int TRACE_LEVEL_ACTIONS = 30;
       
    41 
       
    42     protected static int TRACE_LEVEL_SOCKETS = 40;
       
    43 
       
    44     protected static int TRACE_LEVEL_IO = 50;
       
    45 
       
    46     protected String name = null;
       
    47 
       
    48     protected ServerSocket serverSocket = null;
       
    49 
       
    50     protected Socket socket = null;
       
    51 
       
    52     protected InputStream sin = null;
       
    53 
       
    54     protected OutputStream sout = null;
       
    55 
       
    56     protected Process connectingProcess = null;
       
    57 
       
    58     protected volatile boolean connected = false;
       
    59 
       
    60     protected volatile boolean closed = false;
       
    61 
       
    62     protected volatile boolean connectionClosed = false;
       
    63 
       
    64     protected volatile boolean shouldStop = false;
       
    65 
       
    66     protected Log.Logger logger = null;
       
    67 
       
    68     /**
       
    69      * Make an empty connection with specified name.
       
    70      *
       
    71      * @param logger
       
    72      *                Logger object for printing log messages
       
    73      * @param name
       
    74      *                connection name
       
    75      */
       
    76     public BasicSocketConnection(Log.Logger logger, String name) {
       
    77         this.logger = logger;
       
    78         this.name = name;
       
    79     }
       
    80 
       
    81     /**
       
    82      * Try to bind connection to the local port.
       
    83      *
       
    84      * @param port
       
    85      *                port number to bind to
       
    86      *
       
    87      * @throws IOException
       
    88      *                 if error occured while binding
       
    89      */
       
    90     protected void tryBind(int port) throws IOException {
       
    91         logger.trace(TRACE_LEVEL_IO, "Binding for " + name + " connection to port: " + port);
       
    92         serverSocket = new ServerSocket(port, 1);
       
    93         logger.trace(TRACE_LEVEL_IO, "Bound for " + name + " connection to port: " + port);
       
    94     }
       
    95 
       
    96     /**
       
    97      * Bind connection to the local port for specified timeout.
       
    98      *
       
    99      * @param port
       
   100      *                port number to bind to
       
   101      * @param timeout
       
   102      *                binding timeout in milliseconds
       
   103      *
       
   104      * @throws Failure
       
   105      *                 if error ocured while binding
       
   106      */
       
   107     protected void bind(int port, long timeout) {
       
   108         BindException bindException = null;
       
   109         long timeToFinish = System.currentTimeMillis() + timeout;
       
   110         for (long i = 0; !shouldStop && (timeout == 0 || System.currentTimeMillis() < timeToFinish); i++) {
       
   111             try {
       
   112                 tryBind(port);
       
   113                 return;
       
   114             } catch (BindException e) {
       
   115                 bindException = e;
       
   116                 logger.display("Attempt #" + i + " to bind to port " + port + " failed:\n\t" + e);
       
   117                 try {
       
   118                     Thread.sleep(DebugeeBinder.CONNECT_TRY_DELAY);
       
   119                 } catch (InterruptedException ie) {
       
   120                     ie.printStackTrace(logger.getOutStream());
       
   121                     throw new Failure("Thread interrupted while binding for " + name + " connection to port " + port + ":\n\t" + ie);
       
   122                 }
       
   123             } catch (IOException e) {
       
   124                 e.printStackTrace(logger.getOutStream());
       
   125                 throw new Failure("Caught IOException while binding for " + name + " connection to port " + port + ":\n\t" + e);
       
   126             }
       
   127         }
       
   128         throw new Failure("Unable to bind for " + name + " connection to port " + port + " for " + timeout + "ms timeout:\n\t" + bindException);
       
   129     }
       
   130 
       
   131     /**
       
   132      * Accept connection at the bound port for specified timeout.
       
   133      *
       
   134      * @param timeout
       
   135      *                accepting timeout in milliseconds
       
   136      *
       
   137      * @throws Failure
       
   138      *                 if error occured while accepting connection
       
   139      */
       
   140     public void accept(long timeout) {
       
   141         int port = serverSocket.getLocalPort();
       
   142         logger.trace(TRACE_LEVEL_IO, "Listening for " + name + " connection at port: " + port);
       
   143         socket = null;
       
   144         try {
       
   145             if (timeout > Integer.MAX_VALUE) {
       
   146                 throw new TestBug("Too large timeout long value: " + timeout + " (can't cast it to int)");
       
   147             }
       
   148 
       
   149             serverSocket.setSoTimeout((int)timeout);
       
   150 
       
   151             long waitStartTime = System.currentTimeMillis();
       
   152 
       
   153             /*
       
   154              * We found that sometimes (very rarely) on Solaris ServerSocket.accept() throws InterruptedIOException
       
   155              * even if connection timeout (specified through ServerSocket.setSoTimeout) didn't expire.
       
   156              * Following code tries to catch such case and call ServerSocket.accept() while timeout didn't expire.
       
   157              */
       
   158             do {
       
   159                 try {
       
   160                     socket = serverSocket.accept();
       
   161                     logger.trace(TRACE_LEVEL_IO, "Accepted " + name + " connection at port: " + port);
       
   162                 } catch (InterruptedIOException e) {
       
   163                     long interruptTime = System.currentTimeMillis();
       
   164                     long waitTime = interruptTime - waitStartTime;
       
   165 
       
   166                     logger.display("Caught InterruptedIOException. Wait start time: " + waitStartTime + ", exception was thrown at: "
       
   167                             + interruptTime + ", wait time: " + (interruptTime - waitStartTime) + ", actual timeout: " + timeout);
       
   168 
       
   169                     // if waitTime was too small call ServerSocket.accept() one more time
       
   170                     if (!shouldStop && (waitTime < (timeout / 2))) {
       
   171                         logger.display("InterruptedIOException was thrown too early, trying to call ServerSocket.accept() one more time");
       
   172                         continue;
       
   173                     } else {
       
   174                         if (!shouldStop) {
       
   175                             logger.complain("Caught InterruptedIOException while listening for " + name + " connection at port " + port + ":\n\t" + e);
       
   176                             throw new Failure("Connection for " + name +
       
   177                                     " at port " + port +
       
   178                                     " wasn't accepted in " + timeout + "ms");
       
   179                         } else {
       
   180                             logger.display("Listening was interrupted (caught InterruptedIOException while listening for " + name + " connection at port " + port + ":\n\t" + e + ")");
       
   181                             break;
       
   182                         }
       
   183                     }
       
   184                 }
       
   185             } while (socket == null);
       
   186 
       
   187         } catch (IOException e) {
       
   188             if (!shouldStop) {
       
   189                 e.printStackTrace(logger.getOutStream());
       
   190                 throw new Failure("Caught IOException while listening for " + name + " connection at port " + port + ":\n\t" + e);
       
   191             } else {
       
   192                 logger.display("Listening was interrupted (caught InterruptedIOException while listening for " + name + " connection at port " + port + ":\n\t" + e + ")");
       
   193             }
       
   194         } finally {
       
   195             closeServerConnection();
       
   196         }
       
   197 
       
   198         if (!shouldStop) {
       
   199             if (socket == null) {
       
   200                 throw new Failure("No " + name + " connection accepted at port " + port + " for " + timeout + "ms timeout");
       
   201             }
       
   202 
       
   203             onConnected();
       
   204         }
       
   205     }
       
   206 
       
   207     /**
       
   208      * Attach connection to the remote host and port.
       
   209      *
       
   210      * @param host
       
   211      *                name of remote host to attach to
       
   212      * @param port
       
   213      *                port number to attach to
       
   214      *
       
   215      * @throws Failure
       
   216      *                 if error occured while attaching
       
   217      */
       
   218     public void attach(String host, int port) {
       
   219         try {
       
   220             logger.trace(TRACE_LEVEL_IO, "Attaching for " + name + " connection to host: " + host + ":" + port);
       
   221             socket = new Socket(host, port);
       
   222             socket.setTcpNoDelay(true);
       
   223             logger.trace(TRACE_LEVEL_IO, "Attached for " + name + " connection to host: " + host + ":" + port);
       
   224         } catch (IOException e) {
       
   225             e.printStackTrace(logger.getOutStream());
       
   226             throw new Failure("Caught IOException while attaching for " + name + " connection to " + host + ":" + port + ":\n\t" + e);
       
   227         }
       
   228         if (!shouldStop) {
       
   229             onConnected();
       
   230         }
       
   231     }
       
   232 
       
   233     /**
       
   234      * Continuously attach to the remote host for the specified timeout.
       
   235      *
       
   236      * @param host
       
   237      *                name of remote host to attach to
       
   238      * @param port
       
   239      *                port number to attach to
       
   240      * @param timeout
       
   241      *                attaching timeout in milliseconds
       
   242      *
       
   243      * @throws Failure
       
   244      *                 if error occured while attaching
       
   245      */
       
   246     public void continueAttach(String host, int port, long timeout) {
       
   247         socket = null;
       
   248         long timeToFinish = System.currentTimeMillis() + timeout;
       
   249         ConnectException lastException = null;
       
   250         logger.trace(TRACE_LEVEL_IO, "Attaching for " + name + " connection to host: " + host + ":" + port);
       
   251         try {
       
   252             for (long i = 0; !shouldStop && (timeout == 0 || System.currentTimeMillis() < timeToFinish); i++) {
       
   253                 try {
       
   254                     socket = new Socket(host, port);
       
   255                     logger.trace(TRACE_LEVEL_IO, "Attached for " + name + " connection to host: " + host + ":" + port);
       
   256                     break;
       
   257                 } catch (ConnectException e) {
       
   258                     logger.display("Attempt #" + i + " to attach for " + name + " connection failed:\n\t" + e);
       
   259                     lastException = e;
       
   260                     // check if listening process still alive
       
   261                     if (!checkConnectingProcess()) {
       
   262                         shouldStop = true;
       
   263                         throw new Failure("Break attaching to " + name + " connection: " + "listening process exited");
       
   264                     }
       
   265                     // sleep between attempts
       
   266                     try {
       
   267                         Thread.sleep(DebugeeBinder.CONNECT_TRY_DELAY);
       
   268                     } catch (InterruptedException ie) {
       
   269                         throw new Failure("Thread interrupted while attaching for " + name + " connection to " + host + ":" + port + ":\n\t" + ie);
       
   270                     }
       
   271                 }
       
   272             }
       
   273 
       
   274         } catch (IOException e) {
       
   275             e.printStackTrace(logger.getOutStream());
       
   276             throw new Failure("Caught IOException while attaching for " + name + " connection to " + host + ":" + port + ":\n\t" + e);
       
   277         }
       
   278 
       
   279         if (!shouldStop) {
       
   280             if (socket == null) {
       
   281                 throw new Failure("Unable to attach for " + name + " connection to " + host + ":" + port + " for " + timeout + "ms timeout:\n\t"
       
   282                         + lastException);
       
   283             }
       
   284 
       
   285             onConnected();
       
   286         }
       
   287     }
       
   288 
       
   289     /**
       
   290      * Set already bound serverSocket for further connection.
       
   291      */
       
   292     public void setServerSocket(ServerSocket serverSocket) {
       
   293         this.serverSocket = serverSocket;
       
   294     }
       
   295 
       
   296     /**
       
   297      * Set already connected socket for connection.
       
   298      */
       
   299     public void setSocket(Socket socket) {
       
   300         this.socket = socket;
       
   301         if (!shouldStop) {
       
   302             onConnected();
       
   303         }
       
   304     }
       
   305 
       
   306     /**
       
   307      * Get socket of already established connection.
       
   308      */
       
   309     public Socket getSocket() {
       
   310         return socket;
       
   311     }
       
   312 
       
   313     /**
       
   314      * Return true if another connecting process is still alive.
       
   315      */
       
   316     public boolean checkConnectingProcess() {
       
   317         if (connectingProcess == null) {
       
   318             // no process to check
       
   319             return true;
       
   320         }
       
   321         try {
       
   322             int exitCode = connectingProcess.exitValue();
       
   323         } catch (IllegalThreadStateException e) {
       
   324             // process is still alive
       
   325             return true;
       
   326         }
       
   327         // process exited
       
   328         return false;
       
   329     }
       
   330 
       
   331     /**
       
   332      * Set another connecting process to control if it is still alive.
       
   333      */
       
   334     public void setConnectingProcess(Process process) {
       
   335         connectingProcess = process;
       
   336     }
       
   337 
       
   338     /**
       
   339      * Check if connection is established.
       
   340      */
       
   341     public boolean isConnected() {
       
   342         return connected;
       
   343     }
       
   344 
       
   345     /**
       
   346      * Close socket and associated streams.
       
   347      */
       
   348     public void close() {
       
   349         if (!closed) {
       
   350             shouldStop = true;
       
   351             closeConnection();
       
   352             closed = true;
       
   353         }
       
   354     }
       
   355 
       
   356     /**
       
   357      * Send the specified byte throw the connection.
       
   358      */
       
   359     public void writeByte(byte b) throws IOException {
       
   360         logger.trace(TRACE_LEVEL_IO, "Writing byte: " + b);
       
   361         sout.write(b);
       
   362         sout.flush();
       
   363         logger.trace(TRACE_LEVEL_IO, "Wrote byte: " + b);
       
   364     }
       
   365 
       
   366     /**
       
   367      * Read a byte and return it or -1.
       
   368      */
       
   369     public int readByte() throws IOException {
       
   370         logger.trace(TRACE_LEVEL_IO, "Reading byte");
       
   371         int b = sin.read();
       
   372         logger.trace(TRACE_LEVEL_IO, "Received byte: " + b);
       
   373         return b;
       
   374     }
       
   375 
       
   376     /**
       
   377      * Perform some actions after connection established.
       
   378      */
       
   379     protected void onConnected() {
       
   380         if (!shouldStop) {
       
   381             setSocketOptions();
       
   382             makeSocketStreams();
       
   383             connected = true;
       
   384         }
       
   385     }
       
   386 
       
   387     /**
       
   388      * Set socket options after connection established.
       
   389      */
       
   390     protected void setSocketOptions() {
       
   391     }
       
   392 
       
   393     /**
       
   394      * Close server socket.
       
   395      */
       
   396     protected void closeServerConnection() {
       
   397         if (serverSocket != null) {
       
   398             try {
       
   399                 serverSocket.close();
       
   400                 logger.trace(TRACE_LEVEL_IO, "ServerSocket closed: " + serverSocket);
       
   401             } catch (IOException e) {
       
   402                 logger.display("# WARNING: " + "Caught IOException while closing ServerSocket of " + name + " connection:\n\t" + e);
       
   403             }
       
   404         }
       
   405     }
       
   406 
       
   407     /**
       
   408      * Close socket of connection to remote host.
       
   409      */
       
   410     protected void closeHostConnection() {
       
   411         if (socket != null) {
       
   412             try {
       
   413                 socket.close();
       
   414                 logger.trace(TRACE_LEVEL_IO, "Socket closed: " + socket);
       
   415             } catch (IOException e) {
       
   416                 logger.display("# WARNING: " + "Caught IOException while closing socket of " + name + " connection:\n\t" + e);
       
   417             }
       
   418         }
       
   419     }
       
   420 
       
   421     /**
       
   422      * Close socket streams.
       
   423      */
       
   424     protected void closeSocketStreams() {
       
   425         if (sout != null) {
       
   426             try {
       
   427                 logger.trace(TRACE_LEVEL_IO, "Closing socket output stream: " + sout);
       
   428                 sout.close();
       
   429                 logger.trace(TRACE_LEVEL_IO, "Output stream closed: " + sout);
       
   430             } catch (IOException e) {
       
   431                 logger.display("# WARNING: " + "Caught IOException while closing OutputStream of " + name + " connection:\n\t" + e);
       
   432             }
       
   433         }
       
   434         if (sin != null) {
       
   435             try {
       
   436                 logger.trace(TRACE_LEVEL_IO, "Closing socket input stream: " + sin);
       
   437                 sin.close();
       
   438                 logger.trace(TRACE_LEVEL_IO, "Input stream closed: " + sin);
       
   439             } catch (IOException e) {
       
   440                 logger.display("# WARNING: " + "Caught IOException while closing InputStream of" + name + " connection:\n\t" + e);
       
   441             }
       
   442         }
       
   443     }
       
   444 
       
   445     /**
       
   446      * Close sockets and associated streams.
       
   447      */
       
   448     protected void closeConnection() {
       
   449         if (connectionClosed)
       
   450             return;
       
   451 
       
   452         logger.trace(TRACE_LEVEL_IO, "Closing " + name + " connection");
       
   453         closeSocketStreams();
       
   454         closeHostConnection();
       
   455         closeServerConnection();
       
   456         connectionClosed = true;
       
   457     }
       
   458 
       
   459     /**
       
   460      * Make up socket streams after connection established.
       
   461      */
       
   462     protected void makeSocketStreams() {
       
   463         try {
       
   464             logger.trace(TRACE_LEVEL_IO, "Getting input/output socket streams for " + name + " connection");
       
   465             sout = socket.getOutputStream();
       
   466             logger.trace(TRACE_LEVEL_IO, "Got socket output stream: " + sout);
       
   467             sin = socket.getInputStream();
       
   468             logger.trace(TRACE_LEVEL_IO, "Got socket input stream: " + sin);
       
   469         } catch (IOException e) {
       
   470             e.printStackTrace(logger.getOutStream());
       
   471             throw new Failure("Caught exception while making streams for " + name + " connection:\n\t" + e);
       
   472         }
       
   473     }
       
   474 
       
   475 } // BasicSocketConnection
       
   476 
       
   477 /**
       
   478  * This class implements connection channel via TCP/IP sockets. After connection
       
   479  * established special inner threads are started, which periodically test the
       
   480  * connection by pinging each other. If ping timeout occurs connection is closed
       
   481  * and any thread waiting for read from this connection gets exception.
       
   482  *
       
   483  * @see #setPingTimeout(long)
       
   484  */
       
   485 public class SocketConnection extends BasicSocketConnection {
       
   486 
       
   487     private static final long PING_INTERVAL = 1 * 1000; // milliseconds
       
   488 
       
   489     private static byte DATA_BYTE = (byte) 0x03;
       
   490 
       
   491     private static byte DISCONNECT_BYTE = (byte) 0x04;
       
   492 
       
   493     private final Object inLock = new Object();
       
   494     private ObjectInputStream in = null;
       
   495 
       
   496     private final Object outLock = new Object();
       
   497     private ObjectOutputStream out = null;
       
   498 
       
   499     private volatile long pingTimeout = 0; // don't use ping
       
   500 
       
   501     /**
       
   502      * Make an empty connection with specified name.
       
   503      *
       
   504      * @param log
       
   505      *                Log object for printing log messages
       
   506      * @param name
       
   507      *                connection name
       
   508      */
       
   509     public SocketConnection(Log log, String name) {
       
   510         this(new Log.Logger(log, name + " connection> "), name);
       
   511     }
       
   512 
       
   513     /**
       
   514      * Make an empty connection with specified name.
       
   515      *
       
   516      * @param logger
       
   517      *                Logger object for printing log messages
       
   518      * @param name
       
   519      *                connection name
       
   520      */
       
   521     public SocketConnection(Log.Logger logger, String name) {
       
   522         super(logger, name);
       
   523     }
       
   524 
       
   525     /**
       
   526      * Set ping timeout in milliseconds (0 means don't use ping at all).
       
   527      */
       
   528     public void setPingTimeout(long timeout) {
       
   529         logger.display("# WARNING: Setting ping timeout for " + name + " connection ingnored: " + timeout + " ms");
       
   530         pingTimeout = timeout;
       
   531     }
       
   532 
       
   533     /**
       
   534      * Returns value of current ping timeout in milliseconds (0 means ping is
       
   535      * not used).
       
   536      */
       
   537     public long getPingTimeout() {
       
   538         return pingTimeout;
       
   539     }
       
   540 
       
   541     /**
       
   542      * Receive an object from remote host.
       
   543      */
       
   544     public Object readObject() {
       
   545         if (!isConnected()) {
       
   546             throw new Failure("Unable to read object from not established " + name + " connection");
       
   547         }
       
   548 
       
   549         try {
       
   550             return doReadObject();
       
   551         } catch (EOFException e) {
       
   552             return null;
       
   553         } catch (Exception e) {
       
   554             e.printStackTrace(logger.getOutStream());
       
   555             throw new Failure("Caught Exception while reading an object from " + name + " connection:\n\t" + e);
       
   556         }
       
   557     }
       
   558 
       
   559     /**
       
   560      * Send an object to remote host.
       
   561      */
       
   562     public void writeObject(Object object) {
       
   563         if (!isConnected()) {
       
   564             throw new Failure("Unable to send object throw not established " + name + " connection:\n\t" + object);
       
   565         }
       
   566 
       
   567         try {
       
   568             doWriteObject(object);
       
   569         } catch (IOException e) {
       
   570             e.printStackTrace(logger.getOutStream());
       
   571             throw new Failure("Caught IOException while writing an object to " + name + " connection:\n\t" + e);
       
   572         }
       
   573     }
       
   574 
       
   575     /**
       
   576      * Close socket and associated streams and finish all internal threads.
       
   577      */
       
   578     public void close() {
       
   579         if (!closed) {
       
   580             // disconnect();
       
   581             shouldStop = true;
       
   582             super.close();
       
   583             closed = true;
       
   584         }
       
   585     }
       
   586 
       
   587     /**
       
   588      * Perform some actions after connection has established.
       
   589      */
       
   590     protected void onConnected() {
       
   591         super.onConnected();
       
   592     }
       
   593 
       
   594     /**
       
   595      * Do write an object to the connection channel.
       
   596      */
       
   597     private void doWriteObject(Object object) throws IOException {
       
   598         logger.trace(TRACE_LEVEL_IO, "writing object: " + object);
       
   599         synchronized(outLock) {
       
   600             out.writeObject(object);
       
   601             out.flush();
       
   602         }
       
   603         logger.trace(TRACE_LEVEL_PACKETS, "* sent: " + object);
       
   604     }
       
   605 
       
   606     /**
       
   607      * Do read an object from the connection channel.
       
   608      */
       
   609     private Object doReadObject() throws IOException, ClassNotFoundException {
       
   610         logger.trace(TRACE_LEVEL_IO, "Reading object");
       
   611         Object object = null;
       
   612         synchronized(inLock) {
       
   613             object = in.readObject();
       
   614         }
       
   615         logger.trace(TRACE_LEVEL_PACKETS, "* recv: " + object);
       
   616         return object;
       
   617     }
       
   618 
       
   619     /**
       
   620      * Close socket streams.
       
   621      */
       
   622     protected void closeSocketStreams() {
       
   623         synchronized(outLock) {
       
   624             if (out != null) {
       
   625                 try {
       
   626                     logger.trace(TRACE_LEVEL_IO, "Closing socket output stream: " + out);
       
   627                     out.close();
       
   628                     logger.trace(TRACE_LEVEL_IO, "Output stream closed: " + out);
       
   629                 } catch (IOException e) {
       
   630                     logger.display("# WARNING: " + "Caught IOException while closing ObjectOutputStream of " + name + " connection:\n\t" + e);
       
   631                 }
       
   632             }
       
   633         }
       
   634         synchronized(inLock) {
       
   635             if (in != null) {
       
   636                 try {
       
   637                     logger.trace(TRACE_LEVEL_IO, "Closing socket input stream: " + in);
       
   638                     in.close();
       
   639                     logger.trace(TRACE_LEVEL_IO, "Input stream closed: " + in);
       
   640                 } catch (IOException e) {
       
   641                     logger.display("# WARNING: " + "Caught IOException while closing ObjectInputStream of" + name + " connection:\n\t" + e);
       
   642                 }
       
   643             }
       
   644         }
       
   645         super.closeSocketStreams();
       
   646     }
       
   647 
       
   648     /**
       
   649      * Close sockets and associated streams.
       
   650      */
       
   651     protected void closeConnection() {
       
   652         if (connectionClosed)
       
   653             return;
       
   654         connected = false;
       
   655         shouldStop = true;
       
   656         super.closeConnection();
       
   657     }
       
   658 
       
   659     /**
       
   660      * Make up object streams for socket.
       
   661      */
       
   662     protected void makeSocketStreams() {
       
   663         try {
       
   664             logger.trace(TRACE_LEVEL_IO, "Making input/output object streams for " + name + " connection");
       
   665             synchronized(outLock) {
       
   666                 out = new ObjectOutputStream(socket.getOutputStream());
       
   667                 out.flush();
       
   668             }
       
   669             logger.trace(TRACE_LEVEL_IO, "Output stream created: " + out);
       
   670             synchronized(inLock) {
       
   671                 in = new ObjectInputStream(socket.getInputStream());
       
   672             }
       
   673             logger.trace(TRACE_LEVEL_IO, "Input stream created: " + in);
       
   674         } catch (IOException e) {
       
   675             e.printStackTrace(logger.getOutStream());
       
   676             throw new Failure("Caught exception while making streams for " + name + " connection:\n\t" + e);
       
   677         }
       
   678     }
       
   679 
       
   680 } // SocketConnection