8144144: ORB destroy() leaks filedescriptors after unsuccessful connection
Reviewed-by: chegar, coffeys
--- 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.