Fixed a bug when there are too many open sockets.

Also, some minor corrections to shutdown() in ConnectionHandler.

Change-Id: I937f200c14c185b0867f997645d8b288a19b9889
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java
index 2ffb48f..c356a10 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java
@@ -32,6 +32,10 @@
 
     private static final String LOG_TAG = "ConnectionHandler";
 
+    public static interface OnFinishedCallback {
+        public void onFinished();
+    }
+
     private class SocketPipeThread extends Thread {
 
         private Socket mInSocket, mOutSocket;
@@ -69,6 +73,9 @@
                     break;
                 }
             }
+
+            ConnectionHandler.this.stop();
+            mOnFinishedCallback.onFinished();
         }
 
         @Override
@@ -80,6 +87,8 @@
     private Socket mFromSocket, mToSocket;
     private SocketPipeThread mFromToPipe, mToFromPipe;
 
+    private OnFinishedCallback mOnFinishedCallback;
+
     public ConnectionHandler(Socket fromSocket, Socket toSocket) {
         mFromSocket = fromSocket;
         mToSocket = toSocket;
@@ -87,6 +96,10 @@
         mToFromPipe = new SocketPipeThread(mToSocket, mFromSocket);
     }
 
+    public void registerOnConnectionHandlerFinishedCallback(OnFinishedCallback callback) {
+        mOnFinishedCallback = callback;
+    }
+
     public void start() {
         mFromToPipe.start();
         mToFromPipe.start();
@@ -102,17 +115,23 @@
             synchronized (mToFromPipe) {
                 /** This will stop the while loop in the run method */
                 try {
-                    socket.shutdownInput();
+                    if (!socket.isInputShutdown()) {
+                        socket.shutdownInput();
+                    }
                 } catch (IOException e) {
                     Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
                 }
                 try {
-                    socket.shutdownOutput();
+                    if (!socket.isOutputShutdown()) {
+                        socket.shutdownOutput();
+                    }
                 } catch (IOException e) {
                     Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
                 }
                 try {
-                    socket.close();
+                    if (!socket.isClosed()) {
+                        socket.close();
+                    }
                 } catch (IOException e) {
                     Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
                 }
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java
index f948767..1b581fc 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java
@@ -92,14 +92,37 @@
                     continue;
                 }
 
-                ConnectionHandler forwarder = new ConnectionHandler(localSocket, remoteSocket);
-                mConnectionHandlers.add(forwarder);
-                forwarder.start();
+                final ConnectionHandler connectionHandler =
+                        new ConnectionHandler(localSocket, remoteSocket);
 
+                /**
+                 * We have to close the sockets after the ConnectionHandler finishes, so we
+                 * don't get "Too may open files" exception. We also remove the ConnectionHandler
+                 * from the collection to avoid memory issues.
+                 * */
+                ConnectionHandler.OnFinishedCallback callback =
+                        new ConnectionHandler.OnFinishedCallback() {
+                    @Override
+                    public void onFinished() {
+                        removeConncetionHandler(connectionHandler);
+                    }
+                };
+                connectionHandler.registerOnConnectionHandlerFinishedCallback(callback);
+
+                mConnectionHandlers.add(connectionHandler);
+                connectionHandler.start();
             }
         }
     }
 
+    private synchronized void removeConncetionHandler(ConnectionHandler connectionHandler) {
+        if (mConnectionHandlers.remove(connectionHandler)) {
+            Log.d(LOG_TAG, "removeConnectionHandler(): removed");
+        } else {
+            Log.d(LOG_TAG, "removeConnectionHandler(): not in the collection");
+        }
+    }
+
     public void finish() {
         try {
             mServerSocket.close();