8144144: ORB destroy() leaks filedescriptors after unsuccessful connection
authormsheppar
Tue, 16 Feb 2016 12:37:44 +0000
changeset 36019 f5596d6af0de
parent 35814 6c644cca3f3f
child 36020 5924078ce428
8144144: ORB destroy() leaks filedescriptors after unsuccessful connection Reviewed-by: chegar, coffeys
corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/CorbaInboundConnectionCacheImpl.java
corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/CorbaTransportManagerImpl.java
corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java
corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelAcceptorImpl.java
corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java
corba/src/java.corba/share/classes/com/sun/corba/se/pept/transport/InboundConnectionCache.java
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/CorbaInboundConnectionCacheImpl.java	Wed Jul 05 21:20:45 2017 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/CorbaInboundConnectionCacheImpl.java	Tue Feb 16 12:37:44 2016 +0000
@@ -54,11 +54,17 @@
 {
     protected Collection connectionCache;
 
+    private Acceptor acceptor;
+
     public CorbaInboundConnectionCacheImpl(ORB orb, Acceptor acceptor)
     {
         super(orb, acceptor.getConnectionCacheType(),
               ((CorbaAcceptor)acceptor).getMonitoringName());
         this.connectionCache = new ArrayList();
+        this.acceptor = acceptor;
+        if (orb.transportDebugFlag) {
+            dprint(": " + acceptor );
+        }
     }
 
     ////////////////////////////////////////////////////
@@ -66,11 +72,25 @@
     // pept.transport.InboundConnectionCache
     //
 
+    public void close () {
+
+        super.close();
+        if (orb.transportDebugFlag) {
+            dprint(".close: " + acceptor );
+        }
+        this.acceptor.close();
+
+    }
+
     public Connection get(Acceptor acceptor)
     {
         throw wrapper.methodShouldNotBeCalled();
     }
 
+    public Acceptor getAcceptor () {
+        return acceptor;
+    }
+
     public void put(Acceptor acceptor, Connection connection)
     {
         if (orb.transportDebugFlag) {
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/CorbaTransportManagerImpl.java	Wed Jul 05 21:20:45 2017 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/CorbaTransportManagerImpl.java	Tue Feb 16 12:37:44 2016 +0000
@@ -188,8 +188,9 @@
             for (Object cc : outboundConnectionCaches.values()) {
                 ((ConnectionCache)cc).close() ;
             }
-            for (Object cc : inboundConnectionCaches.values()) {
-                ((ConnectionCache)cc).close() ;
+            for (Object icc : inboundConnectionCaches.values()) {
+                ((ConnectionCache)icc).close() ;
+                unregisterAcceptor(((InboundConnectionCache)icc).getAcceptor());
             }
             getSelector(0).close();
         } finally {
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java	Wed Jul 05 21:20:45 2017 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java	Tue Feb 16 12:37:44 2016 +0000
@@ -26,16 +26,20 @@
 package com.sun.corba.se.impl.transport;
 
 import java.io.IOException;
+import java.net.ServerSocket;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.SelectableChannel;
+import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
+import java.nio.channels.ClosedSelectorException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Iterator;
 import java.util.List;
 
+
 import com.sun.corba.se.pept.broker.Broker;
 import com.sun.corba.se.pept.transport.Acceptor;
 import com.sun.corba.se.pept.transport.Connection;
@@ -111,7 +115,16 @@
                 interestOpsList.add(keyAndOp);
             }
             // tell Selector Thread there's an update to a SelectorKey's Ops
-            selector.wakeup();
+            try {
+                if (selector != null) {
+                    // wakeup Selector thread to process close request
+                    selector.wakeup();
+                }
+            } catch (Throwable t) {
+                if (orb.transportDebugFlag) {
+                    dprint(".registerInterestOps: selector.wakeup: ", t);
+                }
+            }
         }
         else {
             wrapper.selectionKeyInvalid(eventHandler.toString());
@@ -186,7 +199,9 @@
             if (selectionKey != null) {
                 selectionKey.cancel();
             }
-            selector.wakeup();
+            if (selector != null) {
+                selector.wakeup();
+            }
             return;
         }
 
@@ -239,6 +254,8 @@
             readerThread.close();
         }
 
+       clearDeferredRegistrations();
+
         // Selector
 
         try {
@@ -248,7 +265,7 @@
             }
         } catch (Throwable t) {
             if (orb.transportDebugFlag) {
-                dprint(".close: selector.close: " + t);
+                dprint(".close: selector.wakeup: ", t);
             }
         }
     }
@@ -273,15 +290,16 @@
                     n = selector.select(timeout);
                 } catch (IOException  e) {
                     if (orb.transportDebugFlag) {
-                        dprint(".run: selector.select: " + e);
+                        dprint(".run: selector.select: ", e);
                     }
+                } catch (ClosedSelectorException csEx) {
+                    if (orb.transportDebugFlag) {
+                        dprint(".run: selector.select: ", csEx);
+                    }
+                    break;
                 }
                 if (closed) {
-                    selector.close();
-                    if (orb.transportDebugFlag) {
-                        dprint(".run: closed - .run return");
-                    }
-                    return;
+                    break;
                 }
                 /*
                   if (timeout == 0 && orb.transportDebugFlag) {
@@ -321,6 +339,18 @@
                 }
             }
         }
+        try {
+            if (selector != null) {
+                if (orb.transportDebugFlag) {
+                    dprint(".run: selector.close ");
+                }
+                selector.close();
+            }
+        } catch (Throwable t) {
+            if (orb.transportDebugFlag) {
+                dprint(".run: selector.close: ", t);
+            }
+        }
     }
 
     /////////////////////////////////////////////////////
@@ -328,6 +358,44 @@
     // Implementation.
     //
 
+    private void clearDeferredRegistrations() {
+        synchronized (deferredRegistrations) {
+            int deferredListSize = deferredRegistrations.size();
+            if (orb.transportDebugFlag) {
+                dprint(".clearDeferredRegistrations:deferred list size == " + deferredListSize);
+            }
+            for (int i = 0; i < deferredListSize; i++) {
+                EventHandler eventHandler =
+                    (EventHandler)deferredRegistrations.get(i);
+                if (orb.transportDebugFlag) {
+                    dprint(".clearDeferredRegistrations: " + eventHandler);
+                }
+                SelectableChannel channel = eventHandler.getChannel();
+                SelectionKey selectionKey = null;
+
+                try {
+                    if (orb.transportDebugFlag) {
+                        dprint(".clearDeferredRegistrations:close channel == "
+                                + channel);
+                        dprint(".clearDeferredRegistrations:close channel class == "
+                                + channel.getClass().getName());
+                    }
+                    channel.close();
+                    selectionKey = eventHandler.getSelectionKey();
+                    if (selectionKey != null) {
+                        selectionKey.cancel();
+                        selectionKey.attach(null);
+                    }
+                } catch (IOException ioEx) {
+                    if (orb.transportDebugFlag) {
+                        dprint(".clearDeferredRegistrations: ", ioEx);
+                    }
+                }
+            }
+            deferredRegistrations.clear();
+        }
+    }
+
     private synchronized boolean isClosed ()
     {
         return closed;
@@ -344,7 +412,7 @@
             selector = Selector.open();
         } catch (IOException e) {
             if (orb.transportDebugFlag) {
-                dprint(".startSelector: Selector.open: IOException: " + e);
+                dprint(".startSelector: Selector.open: IOException: ", e);
             }
             // REVISIT - better handling/reporting
             RuntimeException rte =
@@ -379,7 +447,7 @@
                                          (Object)eventHandler);
                 } catch (ClosedChannelException e) {
                     if (orb.transportDebugFlag) {
-                        dprint(".handleDeferredRegistrations: " + e);
+                        dprint(".handleDeferredRegistrations: ", e);
                     }
                 }
                 eventHandler.setSelectionKey(selectionKey);
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelAcceptorImpl.java	Wed Jul 05 21:20:45 2017 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelAcceptorImpl.java	Tue Feb 16 12:37:44 2016 +0000
@@ -264,7 +264,12 @@
 
             if (connection.shouldRegisterServerReadEvent()) {
                 Selector selector = orb.getTransportManager().getSelector(0);
-                selector.registerForEvent(connection.getEventHandler());
+                if (selector != null) {
+                    if (orb.transportDebugFlag) {
+                        dprint(".accept: registerForEvent: " + connection);
+                    }
+                    selector.registerForEvent(connection.getEventHandler());
+                }
             }
 
             getConnectionCache().reclaim();
@@ -273,12 +278,15 @@
             if (orb.transportDebugFlag) {
                 dprint(".accept:", e);
             }
-            orb.getTransportManager().getSelector(0).unregisterForEvent(this);
-            // REVISIT - need to close - recreate - then register new one.
-            orb.getTransportManager().getSelector(0).registerForEvent(this);
-            // NOTE: if register cycling we do not want to shut down ORB
-            // since local beans will still work.  Instead one will see
-            // a growing log file to alert admin of problem.
+            Selector selector = orb.getTransportManager().getSelector(0);
+            if (selector != null) {
+                selector.unregisterForEvent(this);
+                // REVISIT - need to close - recreate - then register new one.
+                selector.registerForEvent(this);
+                // NOTE: if register cycling we do not want to shut down ORB
+                // since local beans will still work.  Instead one will see
+                // a growing log file to alert admin of problem.
+            }
         }
     }
 
@@ -289,7 +297,9 @@
                 dprint(".close->:");
             }
             Selector selector = orb.getTransportManager().getSelector(0);
-            selector.unregisterForEvent(this);
+            if (selector != null) {
+                selector.unregisterForEvent(this);
+            }
             if (serverSocketChannel != null) {
                 serverSocketChannel.close();
             }
@@ -480,7 +490,9 @@
             // of calling SelectionKey.interestOps(<interest op>).
 
             Selector selector = orb.getTransportManager().getSelector(0);
-            selector.registerInterestOps(this);
+            if (selector != null) {
+                selector.registerInterestOps(this);
+            }
 
             if (orb.transportDebugFlag) {
                 dprint(".doWork<-:" + this);
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java	Wed Jul 05 21:20:45 2017 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java	Tue Feb 16 12:37:44 2016 +0000
@@ -367,7 +367,10 @@
                 }
             }
             // REVISIT - make sure reader thread is killed.
-            orb.getTransportManager().getSelector(0).unregisterForEvent(this);
+            Selector selector = orb.getTransportManager().getSelector(0);
+            if (selector != null) {
+                selector.unregisterForEvent(this);
+            }
             // Notify anyone waiting.
             purgeCalls(wrapper.connectionAbort(ex), true, false);
             // REVISIT
@@ -801,7 +804,9 @@
             }
             try {
                 Selector selector = orb.getTransportManager().getSelector(0);
-                selector.unregisterForEvent(this);
+                if (selector != null) {
+                    selector.unregisterForEvent(this);
+                }
                 if (socketChannel != null) {
                     socketChannel.close();
                 }
@@ -824,7 +829,9 @@
                dprint(".closeConnectionResources->: " + this);
            }
            Selector selector = orb.getTransportManager().getSelector(0);
-           selector.unregisterForEvent(this);
+           if (selector != null) {
+               selector.unregisterForEvent(this);
+           }
            try {
              if (socketChannel != null)
               socketChannel.close() ;
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/pept/transport/InboundConnectionCache.java	Wed Jul 05 21:20:45 2017 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/pept/transport/InboundConnectionCache.java	Tue Feb 16 12:37:44 2016 +0000
@@ -36,6 +36,8 @@
     public void put(Acceptor acceptor, Connection connection);
 
     public void remove(Connection connection);
+
+    public Acceptor getAcceptor();
 }
 
 // End of file.