summaryrefslogtreecommitdiff
path: root/java/src/IceInternal/OutgoingConnectionFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/IceInternal/OutgoingConnectionFactory.java')
-rw-r--r--java/src/IceInternal/OutgoingConnectionFactory.java219
1 files changed, 88 insertions, 131 deletions
diff --git a/java/src/IceInternal/OutgoingConnectionFactory.java b/java/src/IceInternal/OutgoingConnectionFactory.java
index 02eabeb4e81..638f84aab15 100644
--- a/java/src/IceInternal/OutgoingConnectionFactory.java
+++ b/java/src/IceInternal/OutgoingConnectionFactory.java
@@ -11,6 +11,36 @@ package IceInternal;
public final class OutgoingConnectionFactory
{
+ //
+ // Helper class to to multi hash map.
+ //
+ private static class MultiHashMap<K, V> extends java.util.HashMap<K, java.util.List<V>>
+ {
+ public void
+ put(K key, V value)
+ {
+ java.util.List<V> list = this.get(key);
+ if(list == null)
+ {
+ list = new java.util.LinkedList<V>();
+ this.put(key, list);
+ }
+ list.add(value);
+ }
+
+ public void
+ remove(K key, V value)
+ {
+ java.util.List<V> list = this.get(key);
+ assert(list != null);
+ list.remove(value);
+ if(list.isEmpty())
+ {
+ this.remove(key);
+ }
+ }
+ };
+
interface CreateConnectionCallback
{
void setConnection(Ice.ConnectionI connection, boolean compress);
@@ -40,7 +70,7 @@ public final class OutgoingConnectionFactory
public void
waitUntilFinished()
{
- java.util.Map<ConnectorInfo, java.util.List<Ice.ConnectionI> > connections = null;
+ java.util.Map<Connector, java.util.List<Ice.ConnectionI> > connections = null;
synchronized(this)
{
@@ -65,10 +95,7 @@ public final class OutgoingConnectionFactory
// We want to wait until all connections are finished outside the
// thread synchronization.
//
- if(_connections != null)
- {
- connections = new java.util.HashMap<ConnectorInfo, java.util.List<Ice.ConnectionI> >(_connections);
- }
+ connections = new java.util.HashMap<Connector, java.util.List<Ice.ConnectionI> >(_connections);
}
//
@@ -84,13 +111,24 @@ public final class OutgoingConnectionFactory
synchronized(this)
{
- //
- // For consistency with C#, we set _connections to null rather than to a
- // new empty list so that our finalizer does not try to invoke any
- // methods on member objects.
- //
- _connections = null;
- _connectionsByEndpoint = null;
+ // Ensure all the connections are finished and reapable at this point.
+ java.util.List<Ice.ConnectionI> cons = _reaper.swapConnections();
+ if(cons != null)
+ {
+ int size = 0;
+ for(java.util.List<Ice.ConnectionI> connectionList : _connections.values())
+ {
+ size += connectionList.size();
+ }
+ assert(cons.size() == size);
+ _connections.clear();
+ _connectionsByEndpoint.clear();
+ }
+ else
+ {
+ assert(_connections.isEmpty());
+ assert(_connectionsByEndpoint.isEmpty());
+ }
}
}
@@ -199,14 +237,14 @@ public final class OutgoingConnectionFactory
catch(Ice.CommunicatorDestroyedException ex)
{
exception = ex;
- handleException(exception, ci, connection, hasMore || p.hasNext());
+ handleConnectionException(exception, hasMore || p.hasNext());
connection = null;
break; // No need to continue
}
catch(Ice.LocalException ex)
{
exception = ex;
- handleException(exception, ci, connection, hasMore || p.hasNext());
+ handleConnectionException(exception, hasMore || p.hasNext());
connection = null;
}
}
@@ -346,6 +384,11 @@ public final class OutgoingConnectionFactory
synchronized(this)
{
+ if(_destroyed)
+ {
+ return;
+ }
+
for(java.util.List<Ice.ConnectionI> connectionList : _connections.values())
{
for(Ice.ConnectionI connection : connectionList)
@@ -382,8 +425,8 @@ public final class OutgoingConnectionFactory
throws Throwable
{
IceUtilInternal.Assert.FinalizerAssert(_destroyed);
- IceUtilInternal.Assert.FinalizerAssert(_connections == null);
- IceUtilInternal.Assert.FinalizerAssert(_connectionsByEndpoint == null);
+ //IceUtilInternal.Assert.FinalizerAssert(_connections.isEmpty());
+ //IceUtilInternal.Assert.FinalizerAssert(_connectionsByEndpoint.isEmpty());
IceUtilInternal.Assert.FinalizerAssert(_pendingConnectCount == 0);
IceUtilInternal.Assert.FinalizerAssert(_pending.isEmpty());
@@ -461,12 +504,12 @@ public final class OutgoingConnectionFactory
DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides();
for(ConnectorInfo ci : connectors)
{
- if(_pending.containsKey(ci))
+ if(_pending.containsKey(ci.connector))
{
continue;
}
- java.util.List<Ice.ConnectionI> connectionList = _connections.get(ci);
+ java.util.List<Ice.ConnectionI> connectionList = _connections.get(ci.connector);
if(connectionList == null)
{
continue;
@@ -476,17 +519,6 @@ public final class OutgoingConnectionFactory
{
if(connection.isActiveOrHolding()) // Don't return destroyed or un-validated connections
{
- if(!connection.endpoint().equals(ci.endpoint))
- {
- java.util.List<Ice.ConnectionI> conList = _connectionsByEndpoint.get(ci.endpoint);
- if(conList == null)
- {
- conList = new java.util.LinkedList<Ice.ConnectionI>();
- _connectionsByEndpoint.put(ci.endpoint, conList);
- }
- conList.add(connection);
- }
-
if(defaultsAndOverrides.overrideCompress)
{
compress.value = defaultsAndOverrides.overrideCompressValue;
@@ -543,49 +575,16 @@ public final class OutgoingConnectionFactory
}
//
- // Reap connections for which destruction has completed.
+ // Reap closed connections
//
+ java.util.List<Ice.ConnectionI> cons = _reaper.swapConnections();
+ if(cons != null)
{
- java.util.Iterator<java.util.List<Ice.ConnectionI> > p = _connections.values().iterator();
- while(p.hasNext())
+ for(Ice.ConnectionI c : cons)
{
- java.util.List<Ice.ConnectionI> connectionList = p.next();
- java.util.Iterator<Ice.ConnectionI> q = connectionList.iterator();
- while(q.hasNext())
- {
- Ice.ConnectionI con = q.next();
- if(con.isFinished())
- {
- q.remove();
- }
- }
-
- if(connectionList.isEmpty())
- {
- p.remove();
- }
- }
- }
-
- {
- java.util.Iterator<java.util.List<Ice.ConnectionI> > p = _connectionsByEndpoint.values().iterator();
- while(p.hasNext())
- {
- java.util.List<Ice.ConnectionI> connectionList = p.next();
- java.util.Iterator<Ice.ConnectionI> q = connectionList.iterator();
- while(q.hasNext())
- {
- Ice.ConnectionI con = q.next();
- if(con.isFinished())
- {
- q.remove();
- }
- }
-
- if(connectionList.isEmpty())
- {
- p.remove();
- }
+ _connections.remove(c.connector(), c);
+ _connectionsByEndpoint.remove(c.endpoint(), c);
+ _connectionsByEndpoint.remove(c.endpoint().compress(true), c);
}
}
@@ -662,7 +661,7 @@ public final class OutgoingConnectionFactory
private synchronized Ice.ConnectionI
createConnection(Transceiver transceiver, ConnectorInfo ci)
{
- assert(_pending.containsKey(ci) && transceiver != null);
+ assert(_pending.containsKey(ci.connector) && transceiver != null);
//
// Create and add the connection to the connection map. Adding the connection to the map
@@ -677,7 +676,8 @@ public final class OutgoingConnectionFactory
throw new Ice.CommunicatorDestroyedException();
}
- connection = new Ice.ConnectionI(_instance, transceiver, ci.endpoint.compress(false),null);
+ connection = new Ice.ConnectionI(_instance, _reaper, transceiver, ci.connector,
+ ci.endpoint.compress(false), null);
}
catch(Ice.LocalException ex)
{
@@ -692,20 +692,9 @@ public final class OutgoingConnectionFactory
throw ex;
}
- java.util.List<Ice.ConnectionI> connectionList = _connections.get(ci);
- if(connectionList == null)
- {
- connectionList = new java.util.LinkedList<Ice.ConnectionI>();
- _connections.put(ci, connectionList);
- }
- connectionList.add(connection);
- connectionList = _connectionsByEndpoint.get(ci.endpoint);
- if(connectionList == null)
- {
- connectionList = new java.util.LinkedList<Ice.ConnectionI>();
- _connectionsByEndpoint.put(ci.endpoint, connectionList);
- }
- connectionList.add(connection);
+ _connections.put(ci.connector, connection);
+ _connectionsByEndpoint.put(connection.endpoint(), connection);
+ _connectionsByEndpoint.put(connection.endpoint().compress(true), connection);
return connection;
}
@@ -726,7 +715,7 @@ public final class OutgoingConnectionFactory
{
for(ConnectorInfo c : connectors)
{
- java.util.Set<ConnectCallback> cbs = _pending.remove(c);
+ java.util.Set<ConnectCallback> cbs = _pending.remove(c.connector);
if(cbs != null)
{
for(ConnectCallback cc : cbs)
@@ -790,7 +779,7 @@ public final class OutgoingConnectionFactory
{
for(ConnectorInfo c : connectors)
{
- java.util.Set<ConnectCallback> cbs = _pending.remove(c);
+ java.util.Set<ConnectCallback> cbs = _pending.remove(c.connector);
if(cbs != null)
{
for(ConnectCallback cc : cbs)
@@ -834,7 +823,7 @@ public final class OutgoingConnectionFactory
boolean found = false;
for(ConnectorInfo p : connectors)
{
- java.util.Set<ConnectCallback> cbs = _pending.get(p);
+ java.util.Set<ConnectCallback> cbs = _pending.get(p.connector);
if(cbs != null)
{
found = true;
@@ -857,9 +846,9 @@ public final class OutgoingConnectionFactory
//
for(ConnectorInfo p : connectors)
{
- if(!_pending.containsKey(p))
+ if(!_pending.containsKey(p.connector))
{
- _pending.put(p, new java.util.HashSet<ConnectCallback>());
+ _pending.put(p.connector, new java.util.HashSet<ConnectCallback>());
}
}
@@ -871,7 +860,7 @@ public final class OutgoingConnectionFactory
{
for(ConnectorInfo p : connectors)
{
- java.util.Set<ConnectCallback> cbs = _pending.get(p);
+ java.util.Set<ConnectCallback> cbs = _pending.get(p.connector);
if(cbs != null)
{
cbs.remove(cb);
@@ -880,7 +869,7 @@ public final class OutgoingConnectionFactory
}
private void
- handleException(Ice.LocalException ex, ConnectorInfo ci, Ice.ConnectionI connection, boolean hasMore)
+ handleConnectionException(Ice.LocalException ex, boolean hasMore)
{
TraceLevels traceLevels = _instance.traceLevels();
if(traceLevels.retry >= 2)
@@ -905,38 +894,6 @@ public final class OutgoingConnectionFactory
s.append(ex.toString());
_instance.initializationData().logger.trace(traceLevels.retryCat, s.toString());
}
-
- if(connection != null && connection.isFinished())
- {
- //
- // If the connection is finished, we remove it right away instead of
- // waiting for the reaping.
- //
- // NOTE: it's possible for the connection to not be finished yet.
- //
- synchronized(this)
- {
- java.util.List<Ice.ConnectionI> connectionList = _connections.get(ci);
- if(connectionList != null) // It might have already been reaped!
- {
- connectionList.remove(connection);
- if(connectionList.isEmpty())
- {
- _connections.remove(ci);
- }
- }
-
- connectionList = _connectionsByEndpoint.get(ci.endpoint);
- if(connectionList != null) // It might have already been reaped!
- {
- connectionList.remove(connection);
- if(connectionList.isEmpty())
- {
- _connectionsByEndpoint.remove(ci.endpoint);
- }
- }
- }
- }
}
private void
@@ -1020,7 +977,7 @@ public final class OutgoingConnectionFactory
{
assert(_current != null);
- _factory.handleException(ex, _current, connection, _hasMore || _iter.hasNext());
+ _factory.handleConnectionException(ex, _hasMore || _iter.hasNext());
if(ex instanceof Ice.CommunicatorDestroyedException) // No need to continue.
{
_factory.finishGetConnection(_connectors, ex, this);
@@ -1234,13 +1191,13 @@ public final class OutgoingConnectionFactory
}
private final Instance _instance;
+ private final ConnectionReaper _reaper = new ConnectionReaper();
private boolean _destroyed;
- private java.util.Map<ConnectorInfo, java.util.List<Ice.ConnectionI> > _connections =
- new java.util.HashMap<ConnectorInfo, java.util.List<Ice.ConnectionI> >();
- private java.util.Map<EndpointI, java.util.List<Ice.ConnectionI> > _connectionsByEndpoint =
- new java.util.HashMap<EndpointI, java.util.List<Ice.ConnectionI> >();
- private java.util.Map<ConnectorInfo, java.util.HashSet<ConnectCallback> > _pending =
- new java.util.HashMap<ConnectorInfo, java.util.HashSet<ConnectCallback> >();
+ private MultiHashMap<Connector, Ice.ConnectionI> _connections = new MultiHashMap<Connector, Ice.ConnectionI>();
+ private MultiHashMap<EndpointI, Ice.ConnectionI> _connectionsByEndpoint =
+ new MultiHashMap<EndpointI, Ice.ConnectionI>();
+ private java.util.Map<Connector, java.util.HashSet<ConnectCallback> > _pending =
+ new java.util.HashMap<Connector, java.util.HashSet<ConnectCallback> >();
private int _pendingConnectCount = 0;
}