diff options
Diffstat (limited to 'java/src')
33 files changed, 2034 insertions, 1086 deletions
diff --git a/java/src/Ice/Blobject.java b/java/src/Ice/Blobject.java index 8a9a6a707db..53904e5c4b6 100644 --- a/java/src/Ice/Blobject.java +++ b/java/src/Ice/Blobject.java @@ -15,7 +15,6 @@ public abstract class Blobject extends Ice.Object public abstract byte[] ice_invoke(byte[] inParams, Current current); - /* TODO: Server public IceInternal.DispatchStatus __dispatch(IceInternal.Incoming in, Current current) { @@ -24,8 +23,7 @@ public abstract class Blobject extends Ice.Object int sz = in.is().getReadEncapsSize(); inParams = in.is().readBlob(sz); outParams = ice_invoke(inParams, current); - in.is().writeBlob(outParams); + in.os().writeBlob(outParams); return IceInternal.DispatchStatus.DispatchOK; } - */ } diff --git a/java/src/Ice/CommunicatorI.java b/java/src/Ice/CommunicatorI.java index e78ac9de226..898d6f47022 100644 --- a/java/src/Ice/CommunicatorI.java +++ b/java/src/Ice/CommunicatorI.java @@ -17,6 +17,7 @@ class CommunicatorI implements Communicator { if (_instance != null) { + _instance.objectAdapterFactory().shutdown(); _instance.destroy(); _instance = null; } @@ -64,8 +65,19 @@ class CommunicatorI implements Communicator public ObjectAdapter createObjectAdapter(String name) { - return createObjectAdapterFromProperty(name, "Ice.Adapter." + name + - ".Endpoints"); + ObjectAdapter adapter = + createObjectAdapterFromProperty(name, "Ice.Adapter." + name + + ".Endpoints"); + String router = + _instance.properties().getProperty("Ice.Adapter." + name + + ".Router"); + if (router != null) + { + adapter.addRouter( + RouterPrxHelper.uncheckedCast( + _instance.proxyFactory().stringToProxy(router))); + } + return adapter; } public synchronized ObjectAdapter @@ -180,15 +192,10 @@ class CommunicatorI implements Communicator _instance.logger(logger); } - public Stream - createStream() + public void + setDefaultRouter(RouterPrx router) { - if (_instance == null) - { - throw new CommunicatorDestroyedException(); - } - - return null; + _instance.referenceFactory().setDefaultRouter(router); } CommunicatorI(Properties properties) diff --git a/java/src/Ice/Dispatcher.java b/java/src/Ice/Dispatcher.java deleted file mode 100644 index 9df3cd21383..00000000000 --- a/java/src/Ice/Dispatcher.java +++ /dev/null @@ -1,17 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -package Ice; - -public interface Dispatcher -{ - IceInternal.DispatchStatus - __dispatch(IceInternal.Incoming in, Current current); -} diff --git a/java/src/Ice/Object.java b/java/src/Ice/Object.java index 898f727197d..34af1efcc57 100644 --- a/java/src/Ice/Object.java +++ b/java/src/Ice/Object.java @@ -15,7 +15,6 @@ public class Object public Object() { - _dispatcher = null; } public boolean @@ -55,30 +54,59 @@ public class Object return s.equals("::Ice::Object"); } + public static IceInternal.DispatchStatus + ___ice_isA(Ice.Object __obj, IceInternal.Incoming __in, Current __current) + { + IceInternal.BasicStream __is = __in.is(); + IceInternal.BasicStream __os = __in.os(); + String __id = __is.readString(); + boolean __ret = __obj.ice_isA(__id, __current); + __os.writeBool(__ret); + return IceInternal.DispatchStatus.DispatchOK; + } + public void ice_ping(Current current) { // Nothing to do. } - public Dispatcher - __dispatcher() + public static IceInternal.DispatchStatus + ___ice_ping(Ice.Object __obj, IceInternal.Incoming __in, Current __current) { - return new _ObjectDisp(this); + __obj.ice_ping(__current); + return IceInternal.DispatchStatus.DispatchOK; } - public final IceInternal.DispatchStatus + private static String[] __all = + { + "ice_isA", + "ice_ping" + }; + + public IceInternal.DispatchStatus __dispatch(IceInternal.Incoming in, Current current) { - synchronized (this) + int pos = java.util.Arrays.binarySearch(__all, current.operation); + if (pos < 0) { - if (_dispatcher == null) + return IceInternal.DispatchStatus.DispatchOperationNotExist; + } + + switch (pos) + { + case 0: + { + return ___ice_isA(this, in, current); + } + case 1: { - _dispatcher = __dispatcher(); + return ___ice_ping(this, in, current); } } - return _dispatcher.__dispatch(in, current); + assert(false); + return IceInternal.DispatchStatus.DispatchOperationNotExist; } public void @@ -157,5 +185,4 @@ public class Object private java.util.HashMap _activeFacetMap = new java.util.HashMap(); private java.lang.Object _activeFacetMapMutex = new java.lang.Object(); - private Dispatcher _dispatcher; } diff --git a/java/src/Ice/ObjectAdapterI.java b/java/src/Ice/ObjectAdapterI.java index 3ad2648ab86..7abc61f9cf0 100644 --- a/java/src/Ice/ObjectAdapterI.java +++ b/java/src/Ice/ObjectAdapterI.java @@ -28,16 +28,16 @@ public class ObjectAdapterI implements ObjectAdapter activate() { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } - java.util.ListIterator i = _incomingConnectionFactories.listIterator(); - while (i.hasNext()) + final int sz = _incomingConnectionFactories.size(); + for (int i = 0; i < sz; i++) { IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)i.next(); + (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(i); factory.activate(); } } @@ -45,16 +45,16 @@ public class ObjectAdapterI implements ObjectAdapter public synchronized void hold() { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } - java.util.ListIterator i = _incomingConnectionFactories.listIterator(); - while (i.hasNext()) + final int sz = _incomingConnectionFactories.size(); + for (int i = 0; i < sz; i++) { IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)i.next(); + (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(i); factory.hold(); } } @@ -62,7 +62,7 @@ public class ObjectAdapterI implements ObjectAdapter public synchronized void deactivate() { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { // // Ignore deactivation requests if the Object Adapter has @@ -71,15 +71,17 @@ public class ObjectAdapterI implements ObjectAdapter return; } - java.util.ListIterator i = _incomingConnectionFactories.listIterator(); - while (i.hasNext()) + final int sz = _incomingConnectionFactories.size(); + for (int i = 0; i < sz; i++) { IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)i.next(); + (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(i); factory.destroy(); } _incomingConnectionFactories.clear(); + _instance.outgoingConnectionFactory().removeAdapter(this); + _activeServantMap.clear(); java.util.Iterator p = _locatorMap.values().iterator(); @@ -89,12 +91,14 @@ public class ObjectAdapterI implements ObjectAdapter locator.deactivate(); } _locatorMap.clear(); + + _deactivated = true; } public synchronized ObjectPrx add(Ice.Object servant, Identity ident) { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } @@ -105,9 +109,9 @@ public class ObjectAdapterI implements ObjectAdapter } public synchronized ObjectPrx - addTemporary(Ice.Object servant) + addWithUUID(Ice.Object servant) { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } @@ -115,9 +119,7 @@ public class ObjectAdapterI implements ObjectAdapter long now = System.currentTimeMillis(); Identity ident = new Identity(); ident.category = ""; - ident.name = "." + Long.toHexString(now / 1000L) + "." + - Long.toHexString(now % 1000L) + "." + - Integer.toHexString(_rand.nextInt()); + ident.name = Util.generateUUID(); _activeServantMap.put(ident, servant); @@ -127,7 +129,7 @@ public class ObjectAdapterI implements ObjectAdapter public synchronized void remove(Identity ident) { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } @@ -138,7 +140,7 @@ public class ObjectAdapterI implements ObjectAdapter public synchronized void addServantLocator(ServantLocator locator, String prefix) { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } @@ -149,7 +151,7 @@ public class ObjectAdapterI implements ObjectAdapter public synchronized void removeServantLocator(String prefix) { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } @@ -164,7 +166,7 @@ public class ObjectAdapterI implements ObjectAdapter public synchronized ServantLocator findServantLocator(String prefix) { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } @@ -188,7 +190,7 @@ public class ObjectAdapterI implements ObjectAdapter public synchronized ObjectPrx createProxy(Identity ident) { - if (_incomingConnectionFactories.isEmpty()) + if (_deactivated) { throw new ObjectAdapterDeactivatedException(); } @@ -196,6 +198,94 @@ public class ObjectAdapterI implements ObjectAdapter return newProxy(ident); } + public synchronized ObjectPrx + createReverseProxy(Identity ident) + { + if (_deactivated) + { + throw new ObjectAdapterDeactivatedException(); + } + + // + // Create a reference and return a reverse proxy for this reference. + // + IceInternal.Endpoint[] endpoints = new IceInternal.Endpoint[0]; + IceInternal.Reference ref = + _instance.referenceFactory().create(ident, "", IceInternal.Reference.ModeTwoway, false, endpoints, + endpoints, null, this); + + return _instance.proxyFactory().referenceToProxy(ref); + } + + public synchronized void + addRouter(RouterPrx router) + { + if (_deactivated) + { + throw new ObjectAdapterDeactivatedException(); + } + + IceInternal.RouterInfo routerInfo = _instance.routerManager().get(router); + if (routerInfo != null) + { + // + // Add the router's server proxy endpoints to this object + // adapter. + // + ObjectPrxHelper proxy = (ObjectPrxHelper)routerInfo.getServerProxy(); + IceInternal.Endpoint[] endpoints = proxy.__reference().endpoints; + for (int i = 0; i < endpoints.length; i++) + { + _routerEndpoints.add(endpoints[i]); + } + java.util.Collections.sort(_routerEndpoints); // Must be sorted. + for (int i = 0; i < _routerEndpoints.size() - 1; i++) + { + java.lang.Object o1 = _routerEndpoints.get(i); + java.lang.Object o2 = _routerEndpoints.get(i + 1); + if (o1.equals(o2)) + { + _routerEndpoints.remove(i); + } + } + + // + // Associate this object adapter with the router. This way, + // new outgoing connections to the router's client proxy will + // use this object adapter for callbacks. + // + routerInfo.setAdapter(this); + + // + // Also modify all existing outgoing connections to the + // router's client proxy to use this object adapter for + // callbacks. + // + _instance.outgoingConnectionFactory().setRouter(routerInfo.getRouter()); + } + } + + public synchronized IceInternal.Connection[] + getIncomingConnections() + { + java.util.ArrayList connections = new java.util.ArrayList(); + final int sz = _incomingConnectionFactories.size(); + for (int i = 0; i < sz; i++) + { + IceInternal.IncomingConnectionFactory factory = + (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(i); + IceInternal.Connection[] cons = factory.connections(); + for (int j = 0; j < cons.length; j++) + { + connections.add(cons[j]); + } + } + + IceInternal.Connection[] arr = new IceInternal.Connection[connections.size()]; + connections.toArray(arr); + return arr; + } + // // Only for use by IceInternal.ObjectAdapterFactory // @@ -203,6 +293,7 @@ public class ObjectAdapterI implements ObjectAdapter ObjectAdapterI(IceInternal.Instance instance, String name, String endpts) { _instance = instance; + _deactivated = false; _name = name; String s = endpts.toLowerCase(); @@ -222,7 +313,7 @@ public class ObjectAdapterI implements ObjectAdapter if (end == beg) { - throw new EndpointParseException(); + break; } String es = s.substring(beg, end); @@ -232,11 +323,8 @@ public class ObjectAdapterI implements ObjectAdapter // might change it, for example, to fill in the real port // number if a zero port number is given. // - IceInternal.Endpoint endp = - IceInternal.Endpoint.endpointFromString(instance, es); - _incomingConnectionFactories.add( - new IceInternal.IncomingConnectionFactory(instance, endp, - this)); + IceInternal.Endpoint endp = IceInternal.Endpoint.endpointFromString(instance, es); + _incomingConnectionFactories.add(new IceInternal.IncomingConnectionFactory(instance, endp, this)); if (end == s.length()) { @@ -248,18 +336,24 @@ public class ObjectAdapterI implements ObjectAdapter } catch (LocalException ex) { - if (!_incomingConnectionFactories.isEmpty()) + if (!_deactivated) { deactivate(); } - throw ex; } +// +// Object Adapters without incoming connection factories are +// permissible, as such Object Adapters can still be used with a +// router. (See addRouter.) +// +/* if (_incomingConnectionFactories.isEmpty()) { throw new EndpointParseException(); } +*/ try { @@ -280,7 +374,7 @@ public class ObjectAdapterI implements ObjectAdapter finalize() throws Throwable { - if (!_incomingConnectionFactories.isEmpty()) + if (!_deactivated) { deactivate(); } @@ -292,52 +386,86 @@ public class ObjectAdapterI implements ObjectAdapter newProxy(Identity ident) { IceInternal.Endpoint[] endpoints = - new IceInternal.Endpoint[_incomingConnectionFactories.size()]; - int n = 0; - java.util.ListIterator i = _incomingConnectionFactories.listIterator(); - while (i.hasNext()) + new IceInternal.Endpoint[_incomingConnectionFactories.size() + _routerEndpoints.size()]; + + // + // First we add all endpoints from all incoming connection + // factories. + // + int sz = _incomingConnectionFactories.size(); + for (int i = 0; i < sz; i++) { IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)i.next(); - endpoints[n++] = factory.endpoint(); + (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(i); + endpoints[i] = factory.endpoint(); + } + + // + // Now we also add the endpoints of the router's server proxy, if + // any. This way, object references created by this object adapter + // will also point to the router's server proxy endpoints. + // + sz = _routerEndpoints.size(); + for (int i = 0; i < sz; i++) + { + endpoints[i] = (IceInternal.Endpoint)_routerEndpoints.get(i); } - IceInternal.Reference reference = new IceInternal.Reference(_instance, - ident, "", IceInternal.Reference.ModeTwoway, false, endpoints, - endpoints); + // + // Create a reference and return a proxy for this reference. + // + IceInternal.Reference reference = _instance.referenceFactory().create(ident, "", IceInternal.Reference.ModeTwoway, false, + endpoints, endpoints, null, null); return _instance.proxyFactory().referenceToProxy(reference); } public boolean isLocal(ObjectPrx proxy) { - // TODO: Optimize? IceInternal.Reference ref = ((ObjectPrxHelper)proxy).__reference(); - IceInternal.Endpoint[] endpoints = ref.endpoints; - for (int n = 0; n < endpoints.length; n++) + final IceInternal.Endpoint[] endpoints = ref.endpoints; + + // + // Proxies which have at least one endpoint in common with the + // endpoints used by this object adapter's incoming connection + // factories are considered local. + // + for (int i = 0; i < endpoints.length; i++) { - java.util.ListIterator i = - _incomingConnectionFactories.listIterator(); - while (i.hasNext()) + final int sz = _incomingConnectionFactories.size(); + for (int j = 0; j < sz; j++) { IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)i.next(); - if (factory.equivalent(endpoints[n])) + (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(j); + if (factory.equivalent(endpoints[i])) { return true; } } } + // + // Proxies which have at least one endpoint in common with the + // router's server proxy endpoints (if any), are also considered + // local. + // + for (int i = 0; i < endpoints.length; i++) + { + if (java.util.Collections.binarySearch(_routerEndpoints, endpoints[i]) >= 0) // _routerEndpoints is sorted. + { + return true; + } + } + return false; } private IceInternal.Instance _instance; + private boolean _deactivated; private String _name; - private java.util.LinkedList _incomingConnectionFactories = - new java.util.LinkedList(); private java.util.HashMap _activeServantMap = new java.util.HashMap(); private java.util.HashMap _locatorMap = new java.util.HashMap(); - private java.util.Random _rand = new java.util.Random(); - + private java.util.ArrayList _incomingConnectionFactories = + new java.util.ArrayList(); + private java.util.ArrayList _routerEndpoints = new java.util.ArrayList(); } diff --git a/java/src/Ice/ObjectPrx.java b/java/src/Ice/ObjectPrx.java index 28d12843a70..8de224cba90 100644 --- a/java/src/Ice/ObjectPrx.java +++ b/java/src/Ice/ObjectPrx.java @@ -20,6 +20,9 @@ public interface ObjectPrx public void ice_ping(); public void ice_ping(java.util.Map __context); + //public String[] ice_ids(); + //public String[] ice_ids(java.util.Map __context); + public byte[] ice_invoke(String operation, boolean nonmutating, byte[] inParams); public byte[] ice_invoke(String operation, boolean nonmutating, @@ -47,6 +50,10 @@ public interface ObjectPrx public ObjectPrx ice_timeout(int t); + public ObjectPrx ice_router(Ice.RouterPrx router); + + public ObjectPrx ice_default(); + public void ice_flush(); public boolean equals(java.lang.Object r); diff --git a/java/src/Ice/ObjectPrxHelper.java b/java/src/Ice/ObjectPrxHelper.java index 1019b210cda..93aafe84e7e 100644 --- a/java/src/Ice/ObjectPrxHelper.java +++ b/java/src/Ice/ObjectPrxHelper.java @@ -289,6 +289,38 @@ public class ObjectPrxHelper implements ObjectPrx } } + public final ObjectPrx + ice_router(Ice.RouterPrx router) + { + IceInternal.Reference ref = _reference.changeRouter(router); + if (ref.equals(_reference)) + { + return this; + } + else + { + ObjectPrxHelper proxy = new ObjectPrxHelper(); + proxy.setup(ref); + return proxy; + } + } + + public final ObjectPrx + ice_default() + { + IceInternal.Reference ref = _reference.changeDefault(); + if (ref.equals(_reference)) + { + return this; + } + else + { + ObjectPrxHelper proxy = new ObjectPrxHelper(); + proxy.setup(ref); + return proxy; + } + } + public final void ice_flush() { @@ -313,7 +345,34 @@ public class ObjectPrxHelper implements ObjectPrx __copyFrom(ObjectPrx from) { ObjectPrxHelper h = (ObjectPrxHelper)from; - setup(h.__reference()); + IceInternal.Reference ref = null; + _ObjectDelM delegateM = null; + + synchronized(from) + { + ref = h._reference; + try + { + delegateM = (_ObjectDelM)h._delegate; + } + catch (ClassCastException ex) + { + } + } + + // + // No need to synchronize "*this", as this operation is only + // called upon initialization. + // + + _reference = ref; + + if (delegateM != null) + { + _ObjectDelM delegate = __createDelegateM(); + delegate.__copyFrom(delegateM); + _delegate = delegate; + } } public final synchronized int @@ -419,12 +478,12 @@ public class ObjectPrxHelper implements ObjectPrx */ } - protected final synchronized _ObjectDel + public final synchronized _ObjectDel __getDelegate() { if (_delegate == null) { - /* TODO: Server + /* TODO: Collocated ObjectAdapter adapter = _reference.instance.objectAdapterFactory(). findObjectAdapter(this); if (adapter != null) @@ -439,6 +498,16 @@ public class ObjectPrxHelper implements ObjectPrx _ObjectDelM delegate = __createDelegateM(); delegate.setup(_reference); _delegate = delegate; + + // + // If this proxy is for a non-local object, and we are + // using a router, then add this proxy to the router info + // object. + // + if (_reference.routerInfo != null) + { + _reference.routerInfo.addProxy(this); + } } } diff --git a/java/src/Ice/PropertiesI.java b/java/src/Ice/PropertiesI.java index f0f91aff54e..a5b2bd719ac 100644 --- a/java/src/Ice/PropertiesI.java +++ b/java/src/Ice/PropertiesI.java @@ -184,22 +184,26 @@ class PropertiesI implements Properties s = s.trim(); final char[] arr = s.toCharArray(); - int pos = -1; + int end = -1; for (int i = 0; i < arr.length; i++) { if (arr[i] == ' ' || arr[i] == '\t' || arr[i] == '=') { - pos = i; + end = i; break; } } - if (pos == -1 || pos == s.length() - 1) + if (end == -1) { return; } - String key = s.substring(0, pos); - String value = s.substring(pos + 1).trim(); + String key = s.substring(0, end); + String value = ""; + if (end < s.length()) + { + value = s.substring(end + 1).trim(); + } setProperty(key, value); } diff --git a/java/src/Ice/RoutingTable.java b/java/src/Ice/RoutingTable.java new file mode 100644 index 00000000000..929ff17c79c --- /dev/null +++ b/java/src/Ice/RoutingTable.java @@ -0,0 +1,65 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +package Ice; + +public final class RoutingTable +{ + public + RoutingTable() + { + } + + // + // Returns false if the Proxy exists already. + // + public boolean + add(ObjectPrx prx) + { + if (prx == null) + { + return false; + } + + ObjectPrx proxy = prx.ice_default(); // We insert the proxy in it's default form into the routing table. + + synchronized (this) + { + if (!_table.containsKey(proxy.ice_getIdentity())) + { + _table.put(proxy.ice_getIdentity(), proxy); + return true; + } + else + { + return false; + } + } + } + + // + // Returns null if no Proxy exists for the given identity. + // + public ObjectPrx + get(Identity ident) + { + if (ident.name.length() == 0) + { + return null; + } + + synchronized (this) + { + return (ObjectPrx)_table.get(ident); + } + } + + private java.util.HashMap _table = new java.util.HashMap(); +} diff --git a/java/src/Ice/Util.java b/java/src/Ice/Util.java index 58c970bd331..42a0d5023f5 100644 --- a/java/src/Ice/Util.java +++ b/java/src/Ice/Util.java @@ -83,5 +83,38 @@ public final class Util } } + public static synchronized String + generateUUID() + { + java.rmi.server.UID uid = new java.rmi.server.UID(); + + if (_localAddress == null) + { + java.net.InetAddress addr = null; + try + { + addr = java.net.InetAddress.getLocalHost(); + } + catch (java.net.UnknownHostException ex) + { + throw new DNSException(); + } + byte[] ip = addr.getAddress(); + _localAddress = ""; + for (int i = 0; i < ip.length; i++) + { + if (i > 0) + { + _localAddress += ":"; + } + int n = ip[i] < 0 ? ip[i] + 256 : ip[i]; + _localAddress += Integer.toHexString(n); + } + } + + return _localAddress + ":" + uid; + } + private static Properties _defaultProperties = null; + private static String _localAddress = null; } diff --git a/java/src/Ice/_ObjectDelM.java b/java/src/Ice/_ObjectDelM.java index 9763adbe677..e6681e4f301 100644 --- a/java/src/Ice/_ObjectDelM.java +++ b/java/src/Ice/_ObjectDelM.java @@ -17,8 +17,8 @@ public class _ObjectDelM implements _ObjectDel throws LocationForward, IceInternal.NonRepeatable { IceInternal.Outgoing __out = - new IceInternal.Outgoing(__connection, __reference, false, - "ice_isA", true, __context); + new IceInternal.Outgoing(__connection, __reference, "ice_isA", + true, __context); IceInternal.BasicStream __is = __out.is(); IceInternal.BasicStream __os = __out.os(); __os.writeString(__id); @@ -34,8 +34,8 @@ public class _ObjectDelM implements _ObjectDel throws LocationForward, IceInternal.NonRepeatable { IceInternal.Outgoing __out = - new IceInternal.Outgoing(__connection, __reference, false, - "ice_ping", true, __context); + new IceInternal.Outgoing(__connection, __reference, "ice_ping", + true, __context); if (!__out.invoke()) { throw new UnknownUserException(); @@ -48,8 +48,8 @@ public class _ObjectDelM implements _ObjectDel throws LocationForward, IceInternal.NonRepeatable { IceInternal.Outgoing __out = - new IceInternal.Outgoing(__connection, __reference, false, - operation, nonmutating, __context); + new IceInternal.Outgoing(__connection, __reference, operation, + nonmutating, __context); IceInternal.BasicStream __os = __out.os(); __os.writeBlob(inParams); __out.invoke(); @@ -68,21 +68,114 @@ public class _ObjectDelM implements _ObjectDel __connection.flushBatchRequest(); } - protected IceInternal.Connection __connection; - protected IceInternal.Reference __reference; - // // Only for use by ObjectPrx // final void + __copyFrom(_ObjectDelM from) + { + // + // No need to synchronize "from", as the delegate is immutable + // after creation. + // + + // + // No need to synchronize, as this operation is only called + // upon initialization. + // + + __reference = from.__reference; + __connection = from.__connection; + } + + protected IceInternal.Connection __connection; + protected IceInternal.Reference __reference; + + public void setup(IceInternal.Reference ref) { // // No need to synchronize, as this operation is only called - // upon initial initialization. + // upon initialization. // __reference = ref; + if (__reference.reverseAdapter != null) + { + // + // If we have a reverse object adapter, we use the incoming + // connections from such object adapter. + // + ObjectAdapterI adapter = (ObjectAdapterI)__reference.reverseAdapter; + IceInternal.Connection[] connections = + adapter.getIncomingConnections(); + + IceInternal.Endpoint[] endpoints = + new IceInternal.Endpoint[connections.length]; + for (int i = 0; i < connections.length; i++) + { + endpoints[i] = connections[i].endpoint(); + } + endpoints = filterEndpoints(endpoints); + + if (endpoints.length == 0) + { + throw new NoEndpointException(); + } + + int j; + for (j = 0; j < connections.length; j++) + { + if (connections[j].endpoint().equals(endpoints[0])) + { + break; + } + } + assert(j < connections.length); + __connection = connections[j]; + } + else + { + IceInternal.Endpoint[] endpoints = null; + if (__reference.routerInfo != null) + { + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + ObjectPrx proxy = __reference.routerInfo.getClientProxy(); + endpoints = filterEndpoints(((ObjectPrxHelper)proxy).__reference().endpoints); + } + else + { + endpoints = filterEndpoints(__reference.endpoints); + } + + if (endpoints.length == 0) + { + throw new NoEndpointException(); + } + + IceInternal.OutgoingConnectionFactory factory = + __reference.instance.outgoingConnectionFactory(); + __connection = factory.create(endpoints); + assert(__connection != null); + + // + // If we have a router, add the object adapter for this router (if + // any) to the new connection, so that callbacks from the router + // can be received over this new connection. + // + if (__reference.routerInfo != null) + { + __connection.setAdapter(__reference.routerInfo.getAdapter()); + } + } + } + + private IceInternal.Endpoint[] + filterEndpoints(IceInternal.Endpoint[] allEndpoints) + { java.util.ArrayList endpoints = new java.util.ArrayList(); switch (__reference.mode) { @@ -90,11 +183,14 @@ public class _ObjectDelM implements _ObjectDel case IceInternal.Reference.ModeOneway: case IceInternal.Reference.ModeBatchOneway: { - for (int i = 0; i < __reference.endpoints.length; i++) + // + // Filter out datagram endpoints. + // + for (int i = 0; i < allEndpoints.length; i++) { - if (!__reference.endpoints[i].datagram()) + if (!allEndpoints[i].datagram()) { - endpoints.add(__reference.endpoints[i]); + endpoints.add(allEndpoints[i]); } } break; @@ -103,11 +199,14 @@ public class _ObjectDelM implements _ObjectDel case IceInternal.Reference.ModeDatagram: case IceInternal.Reference.ModeBatchDatagram: { - for (int i = 0; i < __reference.endpoints.length; i++) + // + // Filter out non-datagram endpoints. + // + for (int i = 0; i < allEndpoints.length; i++) { - if (__reference.endpoints[i].datagram()) + if (allEndpoints[i].datagram()) { - endpoints.add(__reference.endpoints[i]); + endpoints.add(allEndpoints[i]); } } break; @@ -117,7 +216,7 @@ public class _ObjectDelM implements _ObjectDel // // Randomize the order of endpoints. // - random_shuffle(endpoints); + java.util.Collections.shuffle(endpoints); IceInternal.Endpoint[] arr; @@ -148,15 +247,7 @@ public class _ObjectDelM implements _ObjectDel java.util.Arrays.sort((java.lang.Object[])arr, __comparator); } - if (arr.length == 0) - { - throw new NoEndpointException(); - } - - IceInternal.OutgoingConnectionFactory factory = - __reference.instance.outgoingConnectionFactory(); - __connection = factory.create(arr); - assert(__connection != null); + return arr; } private static class EndpointComparator implements java.util.Comparator @@ -183,19 +274,4 @@ public class _ObjectDelM implements _ObjectDel } } private static EndpointComparator __comparator = new EndpointComparator(); - - private static java.util.Random __random = new java.util.Random(); - - private static void - random_shuffle(java.util.ArrayList arr) - { - final int sz = arr.size(); - for (int i = 0; i < sz; i++) - { - int pos = Math.abs(__random.nextInt() % sz); - java.lang.Object tmp = arr.get(pos); - arr.set(pos, arr.get(i)); - arr.set(i, tmp); - } - } } diff --git a/java/src/Ice/_ObjectDisp.java b/java/src/Ice/_ObjectDisp.java deleted file mode 100644 index c77c04dee2c..00000000000 --- a/java/src/Ice/_ObjectDisp.java +++ /dev/null @@ -1,77 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -package Ice; - -public class _ObjectDisp implements Dispatcher -{ - public - _ObjectDisp() - { - _delegate = null; - } - - public - _ObjectDisp(Ice.Object delegate) - { - _delegate = delegate; - } - - public static IceInternal.DispatchStatus - ice_isA(Ice.Object __obj, IceInternal.Incoming __in, Current __current) - { - IceInternal.BasicStream __is = __in.is(); - IceInternal.BasicStream __os = __in.os(); - String __id = __is.readString(); - boolean __ret = __obj.ice_isA(__id, __current); - __os.writeBool(__ret); - return IceInternal.DispatchStatus.DispatchOK; - } - - public static IceInternal.DispatchStatus - ice_ping(Ice.Object __obj, IceInternal.Incoming __in, Current __current) - { - __obj.ice_ping(__current); - return IceInternal.DispatchStatus.DispatchOK; - } - - private static String[] __all = - { - "ice_isA", - "ice_ping" - }; - - public IceInternal.DispatchStatus - __dispatch(IceInternal.Incoming in, Current current) - { - int pos = java.util.Arrays.binarySearch(__all, current.operation); - if (pos < 0) - { - return IceInternal.DispatchStatus.DispatchOperationNotExist; - } - - switch (pos) - { - case 0: - { - return ice_isA(_delegate, in, current); - } - case 1: - { - return ice_ping(_delegate, in, current); - } - } - - assert(false); - return IceInternal.DispatchStatus.DispatchOperationNotExist; - } - - private Ice.Object _delegate; -} diff --git a/java/src/IceInternal/BasicStream.java b/java/src/IceInternal/BasicStream.java index 2f770c5425e..27a4903bce8 100644 --- a/java/src/IceInternal/BasicStream.java +++ b/java/src/IceInternal/BasicStream.java @@ -629,6 +629,7 @@ public class BasicStream writeInt(len); if (len > 0) { + /* if (_currentWriteEncaps.stringsWritten == null) { _currentWriteEncaps.stringsWritten = @@ -637,6 +638,7 @@ public class BasicStream int num = _currentWriteEncaps.stringsWritten.size(); _currentWriteEncaps.stringsWritten.put( v, new Integer(-(num + 1))); + */ final char[] arr = v.toCharArray(); expand(len); for (int i = 0; i < len; i++) @@ -734,122 +736,6 @@ public class BasicStream } public void - writeWString(String v) - { - if (_currentWriteEncaps == null) // Lazy initialization - { - _currentWriteEncaps = new WriteEncaps(); - _writeEncapsStack.add(_currentWriteEncaps); - } - - Integer pos = null; - if (_currentWriteEncaps.wstringsWritten != null) // Lazy creation - { - pos = (Integer)_currentWriteEncaps.wstringsWritten.get(v); - } - if (pos != null) - { - writeInt(pos.intValue()); - } - else - { - final int len = v.length(); - writeInt(len); - if (len > 0) - { - if (_currentWriteEncaps.wstringsWritten == null) - { - _currentWriteEncaps.wstringsWritten = - new java.util.HashMap(); - } - int num = _currentWriteEncaps.wstringsWritten.size(); - _currentWriteEncaps.wstringsWritten.put( - v, new Integer(-(num + 1))); - final int sz = len * 2; - expand(sz); - java.nio.CharBuffer charBuf = _buf.asCharBuffer(); - charBuf.put(v); - _buf.position(_buf.position() + sz); - } - } - } - - public void - writeWStringSeq(String[] v) - { - writeInt(v.length); - for (int i = 0; i < v.length; i++) - { - writeWString(v[i]); - } - } - - public String - readWString() - { - final int len = readInt(); - - if (_currentReadEncaps == null) // Lazy initialization - { - _currentReadEncaps = new ReadEncaps(); - _readEncapsStack.add(_currentReadEncaps); - } - - if (len < 0) - { - if (_currentReadEncaps.wstringsRead == null || // Lazy creation - -(len + 1) >= _currentReadEncaps.wstringsRead.size()) - { - throw new Ice.IllegalIndirectionException(); - } - return (String)_currentReadEncaps.wstringsRead.get(-(len + 1)); - } - else - { - if (len == 0) - { - return ""; - } - else - { - try - { - char[] arr = new char[len]; - java.nio.CharBuffer charBuf = _buf.asCharBuffer(); - charBuf.get(arr); - String v = new String(arr); - if (_currentReadEncaps.wstringsRead == null) - { - _currentReadEncaps.wstringsRead = - new java.util.ArrayList(10); - } - _currentReadEncaps.wstringsRead.add(v); - _buf.position(_buf.position() + len * 2); - return v; - } - catch (java.nio.BufferUnderflowException ex) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - } - } - } - - public String[] - readWStringSeq() - { - final int sz = readInt(); - // Don't use resize(sz) or reserve(sz) here, as it cannot be - // checked whether sz is a reasonable value - String[] v = new String[sz]; - for (int i = 0; i < sz; i++) - { - v[i] = readWString(); - } - return v; - } - - public void writeProxy(Ice.ObjectPrx v) { _instance.proxyFactory().proxyToStream(v, this); @@ -888,7 +774,7 @@ public class BasicStream if (_currentWriteEncaps.objectsWritten == null) { _currentWriteEncaps.objectsWritten = - new java.util.HashMap(); + new java.util.IdentityHashMap(); } int num = _currentWriteEncaps.objectsWritten.size(); _currentWriteEncaps.objectsWritten.put(v, new Integer(num)); @@ -1073,7 +959,6 @@ public class BasicStream int start; byte encoding; java.util.ArrayList stringsRead; - java.util.ArrayList wstringsRead; java.util.ArrayList objectsRead; } @@ -1082,8 +967,7 @@ public class BasicStream int start; byte encoding; java.util.HashMap stringsWritten; - java.util.HashMap wstringsWritten; - java.util.HashMap objectsWritten; + java.util.IdentityHashMap objectsWritten; } private java.util.LinkedList _readEncapsStack = new java.util.LinkedList(); diff --git a/java/src/IceInternal/Connection.java b/java/src/IceInternal/Connection.java index 45ae6ecfcf5..52447ebe0ae 100644 --- a/java/src/IceInternal/Connection.java +++ b/java/src/IceInternal/Connection.java @@ -12,75 +12,6 @@ package IceInternal; public final class Connection extends EventHandler { - // DestructionReason - public final static int ObjectAdapterDeactivated = 0; - public final static int CommunicatorDestroyed = 1; - - Connection(Instance instance, Transceiver transceiver, Endpoint endpoint, - Ice.ObjectAdapter adapter) - { - super(instance); - _transceiver = transceiver; - _endpoint = endpoint; - _adapter = adapter; - _threadPool = instance.threadPool(); - _logger = instance.logger(); - _traceLevels = instance.traceLevels(); - _nextRequestId = 1; - _batchStream = new BasicStream(instance); - _responseCount = 0; - _state = StateHolding; - - try - { - String val = - _instance.properties().getProperty("Ice.ConnectionWarnings"); - _warn = Integer.parseInt(val) > 0 ? true : false; - } - catch (NumberFormatException ex) - { - _warn = false; - } - } - - protected void - finalize() - throws Throwable - { - assert(_state == StateClosed); - - super.finalize(); - } - - public void - destroy(int reason) - { - _mutex.lock(); - try - { - switch (reason) - { - case ObjectAdapterDeactivated: - { - setState(StateClosing, - new Ice.ObjectAdapterDeactivatedException()); - break; - } - - case CommunicatorDestroyed: - { - setState(StateClosing, - new Ice.CommunicatorDestroyedException()); - break; - } - } - } - finally - { - _mutex.unlock(); - } - } - public boolean destroyed() { @@ -295,16 +226,60 @@ public final class Connection extends EventHandler public int timeout() { + // No mutex protection necessary, _endpoint is immutable. return _endpoint.timeout(); } + public Endpoint + endpoint() + { + // No mutex protection necessary, _endpoint is immutable. + return _endpoint; + } + + public void + setAdapter(Ice.ObjectAdapter adapter) + { + _mutex.lock(); + try + { + _adapter = adapter; + } + finally + { + _mutex.unlock(); + } + } + + public Ice.ObjectAdapter + getAdapter() + { + _mutex.lock(); + try + { + return _adapter; + } + finally + { + _mutex.unlock(); + } + } + // // Operations from EventHandler // public boolean server() { - return _adapter != null; + _mutex.lock(); + try + { + return _adapter != null; + } + finally + { + _mutex.unlock(); + } } public boolean @@ -477,7 +452,7 @@ public final class Connection extends EventHandler { try { - in.invoke(); + in.invoke(response); } catch (Ice.LocalException ex) { @@ -610,6 +585,75 @@ public final class Connection extends EventHandler } */ + Connection(Instance instance, Transceiver transceiver, Endpoint endpoint, + Ice.ObjectAdapter adapter) + { + super(instance); + _transceiver = transceiver; + _endpoint = endpoint; + _adapter = adapter; + _threadPool = instance.threadPool(); + _logger = instance.logger(); + _traceLevels = instance.traceLevels(); + _nextRequestId = 1; + _batchStream = new BasicStream(instance); + _responseCount = 0; + _state = StateHolding; + + try + { + String val = + _instance.properties().getProperty("Ice.ConnectionWarnings"); + _warn = Integer.parseInt(val) > 0 ? true : false; + } + catch (NumberFormatException ex) + { + _warn = false; + } + } + + protected void + finalize() + throws Throwable + { + assert(_state == StateClosed); + + super.finalize(); + } + + // DestructionReason + public final static int ObjectAdapterDeactivated = 0; + public final static int CommunicatorDestroyed = 1; + + public void + destroy(int reason) + { + _mutex.lock(); + try + { + switch (reason) + { + case ObjectAdapterDeactivated: + { + setState(StateClosing, + new Ice.ObjectAdapterDeactivatedException()); + break; + } + + case CommunicatorDestroyed: + { + setState(StateClosing, + new Ice.CommunicatorDestroyedException()); + break; + } + } + } + finally + { + _mutex.unlock(); + } + } + private static final int StateActive = 0; private static final int StateHolding = 1; private static final int StateClosing = 2; diff --git a/java/src/IceInternal/DispatchStatus.java b/java/src/IceInternal/DispatchStatus.java index 74f53c7099a..789310c51fe 100644 --- a/java/src/IceInternal/DispatchStatus.java +++ b/java/src/IceInternal/DispatchStatus.java @@ -21,25 +21,23 @@ public final class DispatchStatus public static final DispatchStatus DispatchUserException = new DispatchStatus(_DispatchUserException); public static final int _DispatchLocationForward = 2; public static final DispatchStatus DispatchLocationForward = new DispatchStatus(_DispatchLocationForward); - public static final int _DispatchProxyRequested = 3; - public static final DispatchStatus DispatchProxyRequested = new DispatchStatus(_DispatchProxyRequested); - public static final int _DispatchObjectNotExist = 4; + public static final int _DispatchObjectNotExist = 3; public static final DispatchStatus DispatchObjectNotExist = new DispatchStatus(_DispatchObjectNotExist); - public static final int _DispatchFacetNotExist = 5; + public static final int _DispatchFacetNotExist = 4; public static final DispatchStatus DispatchFacetNotExist = new DispatchStatus(_DispatchFacetNotExist); - public static final int _DispatchOperationNotExist = 6; + public static final int _DispatchOperationNotExist = 5; public static final DispatchStatus DispatchOperationNotExist = new DispatchStatus(_DispatchOperationNotExist); - public static final int _DispatchUnknownLocalException = 7; + public static final int _DispatchUnknownLocalException = 6; public static final DispatchStatus DispatchUnknownLocalException = new DispatchStatus(_DispatchUnknownLocalException); - public static final int _DispatchUnknownUserException = 8; + public static final int _DispatchUnknownUserException = 7; public static final DispatchStatus DispatchUnknownUserException = new DispatchStatus(_DispatchUnknownUserException); - public static final int _DispatchUnknownException = 9; + public static final int _DispatchUnknownException = 8; public static final DispatchStatus DispatchUnknownException = new DispatchStatus(_DispatchUnknownException); public static DispatchStatus convert(int val) { - assert val < 10; + assert val < 9; return __values[val]; } diff --git a/java/src/IceInternal/Endpoint.java b/java/src/IceInternal/Endpoint.java index 8694a7ee105..363f73c7782 100644 --- a/java/src/IceInternal/Endpoint.java +++ b/java/src/IceInternal/Endpoint.java @@ -10,7 +10,7 @@ package IceInternal; -public abstract class Endpoint +public abstract class Endpoint implements java.lang.Comparable { public static final short UnknownEndpointType = 0; public static final short TcpEndpointType = 1; @@ -186,4 +186,5 @@ public abstract class Endpoint // Compare endpoints for sorting purposes // public abstract boolean equals(java.lang.Object obj); + public abstract int compareTo(java.lang.Object obj); // From java.lang.Comparable } diff --git a/java/src/IceInternal/Incoming.java b/java/src/IceInternal/Incoming.java index 0ca9f066e39..883776175ec 100644 --- a/java/src/IceInternal/Incoming.java +++ b/java/src/IceInternal/Incoming.java @@ -21,22 +21,12 @@ public class Incoming } public void - invoke() + invoke(boolean response) { Ice.Current current = new Ice.Current(); - boolean gotProxy = _is.readBool(); - if (gotProxy) - { - current.proxy = _is.readProxy(); - current.identity = current.proxy.ice_getIdentity(); - current.facet = current.proxy.ice_getFacet(); - } - else - { - current.identity = new Ice.Identity(); - current.identity.__read(_is); - current.facet = _is.readString(); - } + current.identity = new Ice.Identity(); + current.identity.__read(_is); + current.facet = _is.readString(); current.operation = _is.readString(); current.nonmutating = _is.readBool(); int sz = _is.readInt(); @@ -51,16 +41,23 @@ public class Incoming current.context.put(first, second); } - int statusPos = _os.size(); - _os.writeByte((byte)0); + int statusPos = 0; + if (response) + { + statusPos = _os.size(); + _os.writeByte((byte)0); + } // // Input and output parameters are always sent in an - // encapsulation, which makes it possible to forward oneway - // requests as blobs. + // encapsulation, which makes it possible to forward requests as + // blobs. // _is.startReadEncaps(); - _os.startWriteEncaps(); + if (response) + { + _os.startWriteEncaps(); + } Ice.Object servant = null; Ice.ServantLocator locator = null; @@ -126,23 +123,43 @@ public class Incoming } _is.endReadEncaps(); - _os.endWriteEncaps(); + if (response) + { + _os.endWriteEncaps(); - if (status != DispatchStatus.DispatchOK && - status != DispatchStatus.DispatchUserException) + if (status != DispatchStatus.DispatchOK && + status != DispatchStatus.DispatchUserException) + { + _os.resize(statusPos, false); + _os.writeByte((byte)status.value()); + } + else + { + int save = _os.pos(); + _os.pos(statusPos); + _os.writeByte((byte)status.value()); + _os.pos(save); + } + } + } + catch (Ice.LocationForward ex) + { + if (locator != null && servant != null) { - _os.resize(statusPos, false); - _os.writeByte((byte)status.value()); + assert(_adapter != null); + locator.finished(_adapter, current, servant, cookie.value); } - else + + _is.endReadEncaps(); + if (response) { - int save = _os.pos(); - _os.pos(statusPos); - _os.writeByte((byte)status.value()); - _os.pos(save); + _os.endWriteEncaps(); + _os.resize(statusPos, false); + _os.writeByte((byte)DispatchStatus._DispatchLocationForward); + _os.writeProxy(ex._prx); } } - catch (Ice.LocationForward ex) + catch (Ice.ObjectNotExistException ex) { if (locator != null && servant != null) { @@ -151,14 +168,14 @@ public class Incoming } _is.endReadEncaps(); - _os.endWriteEncaps(); - - _os.resize(statusPos, false); - _os.writeByte((byte)DispatchStatus._DispatchLocationForward); - _os.writeProxy(ex._prx); + if (response) + { + _os.endWriteEncaps(); + _os.resize(statusPos, false); + _os.writeByte((byte)DispatchStatus._DispatchObjectNotExist); + } } - /* - catch (Ice.ProxyRequested ex) + catch (Ice.FacetNotExistException ex) { if (locator != null && servant != null) { @@ -167,12 +184,29 @@ public class Incoming } _is.endReadEncaps(); - _os.endWriteEncaps(); + if (response) + { + _os.endWriteEncaps(); + _os.resize(statusPos, false); + _os.writeByte((byte)DispatchStatus._DispatchFacetNotExist); + } + } + catch (Ice.OperationNotExistException ex) + { + if (locator != null && servant != null) + { + assert(_adapter != null); + locator.finished(_adapter, current, servant, cookie.value); + } - _os.resize(statusPos, false); - _os.writeByte((byte)DispatchStatus._DispatchProxyRequested); + _is.endReadEncaps(); + if (response) + { + _os.endWriteEncaps(); + _os.resize(statusPos, false); + _os.writeByte((byte)DispatchStatus._DispatchOperationNotExist); + } } - */ catch (Ice.LocalException ex) { if (locator != null && servant != null) @@ -182,10 +216,13 @@ public class Incoming } _is.endReadEncaps(); - _os.endWriteEncaps(); - - _os.resize(statusPos, false); - _os.writeByte((byte)DispatchStatus._DispatchUnknownLocalException); + if (response) + { + _os.endWriteEncaps(); + _os.resize(statusPos, false); + _os.writeByte( + (byte)DispatchStatus._DispatchUnknownLocalException); + } throw ex; } @@ -199,10 +236,13 @@ public class Incoming } _is.endReadEncaps(); - _os.endWriteEncaps(); - - _os.resize(statusPos, false); - _os.writeByte((byte)DispatchStatus._DispatchUnknownUserException); + if (response) + { + _os.endWriteEncaps(); + _os.resize(statusPos, false); + _os.writeByte( + (byte)DispatchStatus._DispatchUnknownUserException); + } throw ex; } @@ -216,10 +256,12 @@ public class Incoming } _is.endReadEncaps(); - _os.endWriteEncaps(); - - _os.resize(statusPos, false); - _os.writeByte((byte)DispatchStatus._DispatchUnknownException); + if (response) + { + _os.endWriteEncaps(); + _os.resize(statusPos, false); + _os.writeByte((byte)DispatchStatus._DispatchUnknownException); + } Ice.UnknownException ue = new Ice.UnknownException(); ue.initCause(ex); diff --git a/java/src/IceInternal/IncomingConnectionFactory.java b/java/src/IceInternal/IncomingConnectionFactory.java index e0d19f65356..eb261376ebf 100644 --- a/java/src/IceInternal/IncomingConnectionFactory.java +++ b/java/src/IceInternal/IncomingConnectionFactory.java @@ -12,69 +12,6 @@ package IceInternal; public class IncomingConnectionFactory extends EventHandler { - public - IncomingConnectionFactory(Instance instance, Endpoint endpoint, - Ice.ObjectAdapter adapter) - { - super(instance); - _endpoint = endpoint; - _adapter = adapter; - _state = StateHolding; - - try - { - String val = - _instance.properties().getProperty("Ice.ConnectionWarnings"); - _warn = Integer.parseInt(val) > 0 ? true : false; - } - catch (NumberFormatException ex) - { - _warn = false; - } - - try - { - EndpointHolder h = new EndpointHolder(); - h.value = _endpoint; - _transceiver = _endpoint.serverTransceiver(h); - if (_transceiver != null) - { - _endpoint = h.value; - Connection connection = new Connection(_instance, _transceiver, - _endpoint, _adapter); - _connections.add(connection); - } - else - { - h.value = _endpoint; - _acceptor = _endpoint.acceptor(h); - _endpoint = h.value; - assert(_acceptor != null); - _acceptor.listen(); - _threadPool = _instance.threadPool(); - } - } - catch (RuntimeException ex) - { - setState(StateClosed); - throw ex; - } - } - - protected void - finalize() - throws Throwable - { - assert(_state == StateClosed); - super.finalize(); - } - - public synchronized void - destroy() - { - setState(StateClosed); - } - public synchronized void hold() { @@ -90,6 +27,7 @@ public class IncomingConnectionFactory extends EventHandler public Endpoint endpoint() { + // No mutex protection necessary, _endpoint is immutable. return _endpoint; } @@ -105,6 +43,27 @@ public class IncomingConnectionFactory extends EventHandler return endp.equivalent(_acceptor); } + public synchronized Connection[] + connections() + { + // + // Reap destroyed connections + // + java.util.ListIterator iter = _connections.listIterator(); + while (iter.hasNext()) + { + Connection connection = (Connection)iter.next(); + if (connection.destroyed()) + { + iter.remove(); + } + } + + Connection[] arr = new Connection[_connections.size()]; + _connections.toArray(arr); + return arr; + } + // // Operations from EventHandler // @@ -137,7 +96,7 @@ public class IncomingConnectionFactory extends EventHandler } // - // First reap destroyed connections + // Reap destroyed connections // java.util.ListIterator iter = _connections.listIterator(); while (iter.hasNext()) @@ -212,6 +171,69 @@ public class IncomingConnectionFactory extends EventHandler } */ + public + IncomingConnectionFactory(Instance instance, Endpoint endpoint, + Ice.ObjectAdapter adapter) + { + super(instance); + _endpoint = endpoint; + _adapter = adapter; + _state = StateHolding; + + try + { + String val = + _instance.properties().getProperty("Ice.ConnectionWarnings"); + _warn = Integer.parseInt(val) > 0 ? true : false; + } + catch (NumberFormatException ex) + { + _warn = false; + } + + try + { + EndpointHolder h = new EndpointHolder(); + h.value = _endpoint; + _transceiver = _endpoint.serverTransceiver(h); + if (_transceiver != null) + { + _endpoint = h.value; + Connection connection = new Connection(_instance, _transceiver, + _endpoint, _adapter); + _connections.add(connection); + } + else + { + h.value = _endpoint; + _acceptor = _endpoint.acceptor(h); + _endpoint = h.value; + assert(_acceptor != null); + _acceptor.listen(); + _threadPool = _instance.threadPool(); + } + } + catch (RuntimeException ex) + { + setState(StateClosed); + throw ex; + } + } + + protected void + finalize() + throws Throwable + { + assert(_state == StateClosed); + super.finalize(); + } + + public synchronized void + destroy() + { + setState(StateClosed); + } + private static final int StateActive = 0; private static final int StateHolding = 1; private static final int StateClosed = 2; diff --git a/java/src/IceInternal/Instance.java b/java/src/IceInternal/Instance.java index b63a1451af7..cfad5195615 100644 --- a/java/src/IceInternal/Instance.java +++ b/java/src/IceInternal/Instance.java @@ -42,6 +42,32 @@ public class Instance return _traceLevels; } + public String + defaultProtocol() + { + // No synchronization necessary + return _defaultProtocol; + } + + public String + defaultHost() + { + // No synchronization necessary + return _defaultHost; + } + + public synchronized RouterManager + routerManager() + { + return _routerManager; + } + + public synchronized ReferenceFactory + referenceFactory() + { + return _referenceFactory; + } + public synchronized ProxyFactory proxyFactory() { @@ -78,20 +104,6 @@ public class Instance return _threadPool; } - public String - defaultProtocol() - { - // No synchronization necessary - return _defaultProtocol; - } - - public String - defaultHost() - { - // No synchronization necessary - return _defaultHost; - } - // // TODO: This should be synchronized, but it causes a deadlock // on shutdown if a BasicStream is created while the Instance @@ -116,12 +128,6 @@ public class Instance { _logger = new Ice.LoggerI(); _traceLevels = new TraceLevels(_properties); - _proxyFactory = new ProxyFactory(this); - _outgoingConnectionFactory = new OutgoingConnectionFactory(this); - _servantFactoryManager = new ObjectFactoryManager(); - _userExceptionFactoryManager = new UserExceptionFactoryManager(); - _objectAdapterFactory = new ObjectAdapterFactory(this); - _threadPool = new ThreadPool(this); _defaultProtocol = _properties.getProperty("Ice.DefaultProtocol"); if (_defaultProtocol == null) { @@ -132,6 +138,21 @@ public class Instance { _defaultHost = Network.getLocalHost(true); } + _routerManager = new RouterManager(); + _referenceFactory = new ReferenceFactory(this); + _proxyFactory = new ProxyFactory(this); + String value = _properties.getProperty("Ice.DefaultRouter"); + if (value != null) + { + _referenceFactory.setDefaultRouter( + Ice.RouterPrxHelper.uncheckedCast( + _proxyFactory.stringToProxy(value))); + } + _outgoingConnectionFactory = new OutgoingConnectionFactory(this); + _servantFactoryManager = new ObjectFactoryManager(); + _userExceptionFactoryManager = new UserExceptionFactoryManager(); + _objectAdapterFactory = new ObjectAdapterFactory(this); + _threadPool = new ThreadPool(this); _bufferManager = new BufferManager(); } catch (Ice.LocalException ex) @@ -149,6 +170,8 @@ public class Instance assert(_properties == null); assert(_logger == null); assert(_traceLevels == null); + assert(_routerManager == null); + assert(_referenceFactory == null); assert(_proxyFactory == null); assert(_outgoingConnectionFactory == null); assert(_servantFactoryManager == null); @@ -173,28 +196,33 @@ public class Instance if (_communicator != null) { // Don't destroy the communicator -- the communicator destroys - // this object, not the other way + // this object, not the other way. _communicator = null; } - if (_properties != null) + if (_objectAdapterFactory != null) { - // No destroy function defined - // _properties.destroy(); - _properties = null; + _objectAdapterFactory.shutdown(); // ObjectAdapterFactory has + // shutdown(), not destroy() + _objectAdapterFactory = null; } - if (_logger != null) + if (_servantFactoryManager != null) { - _logger.destroy(); - _logger = null; + _servantFactoryManager.destroy(); + _servantFactoryManager = null; } - if (_traceLevels != null) + if (_userExceptionFactoryManager != null) { - // No destroy function defined - // _traceLevels.destroy(); - _traceLevels = null; + _userExceptionFactoryManager.destroy(); + _userExceptionFactoryManager = null; + } + + if (_referenceFactory != null) + { + _referenceFactory.destroy(); + _referenceFactory = null; } if (_proxyFactory != null) @@ -210,23 +238,10 @@ public class Instance _outgoingConnectionFactory = null; } - if (_servantFactoryManager != null) - { - _servantFactoryManager.destroy(); - _servantFactoryManager = null; - } - - if (_userExceptionFactoryManager != null) - { - _userExceptionFactoryManager.destroy(); - _userExceptionFactoryManager = null; - } - - if (_objectAdapterFactory != null) + if (_routerManager != null) { - _objectAdapterFactory.shutdown(); // ObjectAdapterFactory has - // shutdown(), not destroy() - _objectAdapterFactory = null; + _routerManager.destroy(); + _routerManager = null; } if (_threadPool != null) @@ -237,6 +252,26 @@ public class Instance _threadPool = null; } + if (_properties != null) + { + // No destroy function defined + // _properties.destroy(); + _properties = null; + } + + if (_logger != null) + { + _logger.destroy(); + _logger = null; + } + + if (_traceLevels != null) + { + // No destroy function defined + // _traceLevels.destroy(); + _traceLevels = null; + } + if (_bufferManager != null) { _bufferManager.destroy(); @@ -248,6 +283,8 @@ public class Instance private Ice.Properties _properties; private Ice.Logger _logger; private TraceLevels _traceLevels; + private RouterManager _routerManager; + private ReferenceFactory _referenceFactory; private ProxyFactory _proxyFactory; private OutgoingConnectionFactory _outgoingConnectionFactory; private ObjectFactoryManager _servantFactoryManager; diff --git a/java/src/IceInternal/Outgoing.java b/java/src/IceInternal/Outgoing.java index 529806912c5..138a2ce056e 100644 --- a/java/src/IceInternal/Outgoing.java +++ b/java/src/IceInternal/Outgoing.java @@ -13,8 +13,8 @@ package IceInternal; public final class Outgoing { public - Outgoing(Connection connection, Reference ref, boolean sendProxy, - String operation, boolean nonmutating, java.util.Map context) + Outgoing(Connection connection, Reference ref, String operation, + boolean nonmutating, java.util.Map context) { _connection = connection; _reference = ref; @@ -40,18 +40,8 @@ public final class Outgoing } } - _os.writeBool(sendProxy); - if (sendProxy) - { - Ice.ObjectPrx proxy = _reference.instance.proxyFactory(). - referenceToProxy(_reference); - _os.writeProxy(proxy); - } - else - { - _reference.identity.__write(_os); - _os.writeString(_reference.facet); - } + _reference.identity.__write(_os); + _os.writeString(_reference.facet); _os.writeString(operation); _os.writeBool(nonmutating); if (context == null) @@ -76,8 +66,8 @@ public final class Outgoing // // Input and output parameters are always sent in an - // encapsulation, which makes it possible to forward oneway - // requests as blobs. + // encapsulation, which makes it possible to forward requests as + // blobs. // _os.startWriteEncaps(); } diff --git a/java/src/IceInternal/OutgoingConnectionFactory.java b/java/src/IceInternal/OutgoingConnectionFactory.java index d5b21e4f4b9..3778936c51d 100644 --- a/java/src/IceInternal/OutgoingConnectionFactory.java +++ b/java/src/IceInternal/OutgoingConnectionFactory.java @@ -12,41 +12,6 @@ package IceInternal; public class OutgoingConnectionFactory { - // - // Only for use by Instance - // - OutgoingConnectionFactory(Instance instance) - { - _instance = instance; - } - - protected void - finalize() - throws Throwable - { - assert(_instance == null); - - super.finalize(); - } - - public synchronized void - destroy() - { - if (_instance == null) - { - return; - } - - java.util.Iterator p = _connections.values().iterator(); - while (p.hasNext()) - { - Connection connection = (Connection)p.next(); - connection.destroy(Connection.CommunicatorDestroyed); - } - _connections.clear(); - _instance = null; - } - public synchronized Connection create(Endpoint[] endpoints) { @@ -58,7 +23,7 @@ public class OutgoingConnectionFactory assert(endpoints.length > 0); // - // First reap destroyed connections + // Reap destroyed connections // java.util.Iterator p = _connections.values().iterator(); while (p.hasNext()) @@ -153,6 +118,92 @@ public class OutgoingConnectionFactory return connection; } + public synchronized void + setRouter(Ice.RouterPrx router) + { + if (_instance == null) + { + throw new Ice.CommunicatorDestroyedException(); + } + + RouterInfo routerInfo = _instance.routerManager().get(router); + if (routerInfo != null) + { + // + // Search for connections to the router's client proxy + // endpoints, and update the object adapter for such + // connections, so that callbacks from the router can be + // received over such connections. + // + Ice.ObjectPrx proxy = routerInfo.getClientProxy(); + Ice.ObjectAdapter adapter = routerInfo.getAdapter(); + Endpoint[] endpoints = ((Ice.ObjectPrxHelper)proxy).__reference().endpoints; + for (int i = 0; i < endpoints.length; i++) + { + Connection connection = + (Connection)_connections.get(endpoints[i]); + if (connection != null) + { + connection.setAdapter(adapter); + } + } + } + } + + public synchronized void + removeAdapter(Ice.ObjectAdapter adapter) + { + if (_instance == null) + { + throw new Ice.CommunicatorDestroyedException(); + } + + java.util.Iterator p = _connections.values().iterator(); + while (p.hasNext()) + { + Connection connection = (Connection)p.next(); + if (connection.getAdapter() == adapter) + { + connection.setAdapter(null); + } + } + } + + // + // Only for use by Instance + // + OutgoingConnectionFactory(Instance instance) + { + _instance = instance; + } + + protected void + finalize() + throws Throwable + { + assert(_instance == null); + + super.finalize(); + } + + public synchronized void + destroy() + { + if (_instance == null) + { + return; + } + + java.util.Iterator p = _connections.values().iterator(); + while (p.hasNext()) + { + Connection connection = (Connection)p.next(); + connection.destroy(Connection.CommunicatorDestroyed); + } + _connections.clear(); + _instance = null; + } + private Instance _instance; private java.util.HashMap _connections = new java.util.HashMap(); } diff --git a/java/src/IceInternal/ProxyFactory.java b/java/src/IceInternal/ProxyFactory.java index cf718960e66..ed12373b305 100644 --- a/java/src/IceInternal/ProxyFactory.java +++ b/java/src/IceInternal/ProxyFactory.java @@ -13,17 +13,31 @@ package IceInternal; public final class ProxyFactory { public Ice.ObjectPrx - stringToProxy(String s) + stringToProxy(String str) { - Reference reference = new Reference(_instance, s); - return referenceToProxy(reference); + if (str.length() == 0) + { + return null; + } + else + { + Reference ref = _instance.referenceFactory().create(str); + return referenceToProxy(ref); + } } public String proxyToString(Ice.ObjectPrx proxy) { - Ice.ObjectPrxHelper h = (Ice.ObjectPrxHelper)proxy; - return h.__reference().toString(); + if (proxy != null) + { + Ice.ObjectPrxHelper h = (Ice.ObjectPrxHelper)proxy; + return h.__reference().toString(); + } + else + { + return ""; + } } public Ice.ObjectPrx @@ -38,8 +52,8 @@ public final class ProxyFactory } else { - Reference reference = new Reference(ident, s); - return referenceToProxy(reference); + Reference ref = _instance.referenceFactory().create(ident, s); + return referenceToProxy(ref); } } diff --git a/java/src/IceInternal/Reference.java b/java/src/IceInternal/Reference.java index 7b5918234c0..79c8edc244d 100644 --- a/java/src/IceInternal/Reference.java +++ b/java/src/IceInternal/Reference.java @@ -17,266 +17,12 @@ public final class Reference public final static int ModeBatchOneway = 2; public final static int ModeDatagram = 3; public final static int ModeBatchDatagram = 4; - public final static int ModeBatchLast = ModeBatchDatagram; + public final static int ModeLast = ModeBatchDatagram; - public - Reference(Instance inst, Ice.Identity ident, String fac, int md, - boolean sec, Endpoint[] origEndpts, Endpoint[] endpts) + public int + hashCode() { - instance = inst; - identity = ident; - facet = fac; - mode = md; - secure = sec; - origEndpoints = origEndpts; - endpoints = endpts; - hashValue = 0; - - calcHashValue(); - } - - public - Reference(Instance inst, String str) - { - instance = inst; - mode = ModeTwoway; - secure = false; - hashValue = 0; - facet = ""; - - String s = str.trim(); - if (s.length() == 0) - { - throw new Ice.ReferenceParseException(); - } - - int colon = s.indexOf(':'); - String init; - if (colon == -1) - { - init = s; - } - else - { - init = s.substring(0, colon); - } - - String[] arr = init.split("[ \t\n\r]+"); - identity = Ice.Util.stringToIdentity(arr[0]); - - int i = 1; - while (i < arr.length) - { - String option = arr[i++]; - if (option.length() != 2 || option.charAt(0) != '-') - { - throw new Ice.ReferenceParseException(); - } - - String argument = null; - if (i < arr.length && arr[i].charAt(0) != '-') - { - argument = arr[i++]; - } - - switch (option.charAt(1)) - { - case 'f': - { - if (argument == null) - { - throw new Ice.EndpointParseException(); - } - - facet = argument; - break; - } - - case 't': - { - if (argument != null) - { - throw new Ice.EndpointParseException(); - } - - mode = ModeTwoway; - break; - } - - case 'o': - { - if (argument != null) - { - throw new Ice.EndpointParseException(); - } - - mode = ModeOneway; - break; - } - - case 'O': - { - if (argument != null) - { - throw new Ice.EndpointParseException(); - } - - mode = ModeBatchOneway; - break; - } - - case 'd': - { - if (argument != null) - { - throw new Ice.EndpointParseException(); - } - - mode = ModeDatagram; - break; - } - - case 'D': - { - if (argument != null) - { - throw new Ice.EndpointParseException(); - } - - mode = ModeBatchDatagram; - break; - } - - case 's': - { - if (argument != null) - { - throw new Ice.EndpointParseException(); - } - - secure = true; - break; - } - - default: - { - if (argument != null) - { - throw new Ice.EndpointParseException(); - } - - throw new Ice.ReferenceParseException(); - } - } - } - - java.util.LinkedList origEndpointList = new java.util.LinkedList(); - java.util.LinkedList endpointList = new java.util.LinkedList(); - boolean orig = true; - final int len = s.length(); - int end = colon; - while (end < len && s.charAt(end) == ':') - { - int beg = end + 1; - - end = s.indexOf(':', beg); - if (end == -1) - { - end = len; - } - - if (beg == end) // "::" - { - if (!orig) - { - throw new Ice.ReferenceParseException(); - } - - orig = false; - continue; - } - - String es = s.substring(beg, end); - Endpoint endp = Endpoint.endpointFromString(instance, es); - - if (orig) - { - origEndpointList.add(endp); - } - else - { - endpointList.add(endp); - } - } - - origEndpoints = new Endpoint[origEndpointList.size()]; - origEndpointList.toArray(origEndpoints); - - if (orig) - { - endpoints = origEndpoints; - } - else - { - endpoints = new Endpoint[endpointList.size()]; - endpointList.toArray(endpoints); - } - - if (origEndpoints.length == 0 || endpoints.length == 0) - { - throw new Ice.ReferenceParseException(); - } - - calcHashValue(); - } - - public - Reference(Ice.Identity ident, BasicStream s) - { - instance = s.instance(); - identity = ident; - mode = ModeTwoway; - secure = false; - hashValue = 0; - - // - // Don't read the identity here. Operations calling this - // constructor read the identity, and pass it as a parameter. - // - - facet = s.readString(); - - mode = (int)s.readByte(); - if (mode < 0 || mode > ModeBatchLast) - { - throw new Ice.ProxyUnmarshalException(); - } - - secure = s.readBool(); - - int sz = s.readInt(); - origEndpoints = new Endpoint[sz]; - for (int i = 0; i < sz; i++) - { - origEndpoints[i] = Endpoint.streamRead(s); - } - - boolean same = s.readBool(); - if (same) // origEndpoints == endpoints - { - endpoints = origEndpoints; - } - else - { - sz = s.readInt(); - endpoints = new Endpoint[sz]; - for (int i = 0; i < sz; i++) - { - endpoints[i] = Endpoint.streamRead(s); - } - } - - calcHashValue(); + return hashValue; } public boolean @@ -324,6 +70,22 @@ public final class Reference return false; } + if (routerInfo != r.routerInfo) + { + return false; + } + + if (routerInfo != null && r.routerInfo != null && + !routerInfo.equals(r.routerInfo)) + { + return false; + } + + if (reverseAdapter != r.reverseAdapter) + { + return false; + } + return true; } @@ -372,7 +134,51 @@ public final class Reference toString() { StringBuffer s = new StringBuffer(); - s.append(identity); + s.append(Ice.Util.identityToString(identity)); + + if (facet.length() > 0) + { + s.append(" -f "); + s.append(facet); + } + + switch (mode) + { + case ModeTwoway: + { + s.append(" -t"); + break; + } + + case ModeOneway: + { + s.append(" -o"); + break; + } + + case ModeBatchOneway: + { + s.append(" -O"); + break; + } + + case ModeDatagram: + { + s.append(" -d"); + break; + } + + case ModeBatchDatagram: + { + s.append(" -D"); + break; + } + } + + if (secure) + { + s.append(" -s"); + } for (int i = 0; i < origEndpoints.length; i++) { @@ -401,8 +207,10 @@ public final class Reference public String facet; public int mode; public boolean secure; - public Endpoint[] origEndpoints; // Original endpoints - public Endpoint[] endpoints; // Actual endpoints (set by a loc fwd) + public Endpoint[] origEndpoints; // Original endpoints. + public Endpoint[] endpoints; // Actual endpoints, changed by a location forward. + public RouterInfo routerInfo; // Null if no router is used. + public Ice.ObjectAdapter reverseAdapter; // For reverse communications using the adapter's incoming connections. public int hashValue; // @@ -418,8 +226,9 @@ public final class Reference } else { - return new Reference(instance, newIdentity, facet, mode, secure, - origEndpoints, endpoints); + return instance.referenceFactory().create(newIdentity, facet, mode, secure, + origEndpoints, endpoints, + routerInfo, reverseAdapter); } } @@ -432,14 +241,18 @@ public final class Reference } else { - return new Reference(instance, identity, newFacet, mode, secure, - origEndpoints, endpoints); + return instance.referenceFactory().create(identity, newFacet, mode, secure, + origEndpoints, endpoints, + routerInfo, reverseAdapter); } } public Reference changeTimeout(int timeout) { + // + // We change the timeout settings in all endpoints. + // Endpoint[] newOrigEndpoints = new Endpoint[origEndpoints.length]; for (int i = 0; i < origEndpoints.length; i++) { @@ -452,15 +265,30 @@ public final class Reference newEndpoints[i] = endpoints[i].timeout(timeout); } - Reference ref = new Reference(instance, identity, facet, mode, secure, - newOrigEndpoints, newEndpoints); - - if (ref.equals(this)) + // + // If we have a router, we also change the timeout settings on the + // router and the router's client proxy. + // + RouterInfo newRouterInfo = null; + if (routerInfo != null) { - return this; + try + { + Ice.RouterPrx newRouter = + Ice.RouterPrxHelper.uncheckedCast(routerInfo.getRouter().ice_timeout(timeout)); + Ice.ObjectPrx newClientProxy = routerInfo.getClientProxy().ice_timeout(timeout); + newRouterInfo = instance.routerManager().get(newRouter); + newRouterInfo.setClientProxy(newClientProxy); + } + catch (Ice.NoEndpointException ex) + { + // Ignore non-existing client proxies. + } } - return ref; + return instance.referenceFactory().create(identity, facet, mode, secure, + newOrigEndpoints, newEndpoints, + newRouterInfo, reverseAdapter); } public Reference @@ -472,8 +300,9 @@ public final class Reference } else { - return new Reference(instance, identity, facet, newMode, secure, - origEndpoints, endpoints); + return instance.referenceFactory().create(identity, facet, newMode, secure, + origEndpoints, endpoints, + routerInfo, reverseAdapter); } } @@ -486,8 +315,9 @@ public final class Reference } else { - return new Reference(instance, identity, facet, mode, newSecure, - origEndpoints, endpoints); + return instance.referenceFactory().create(identity, facet, mode, newSecure, + origEndpoints, endpoints, + routerInfo, reverseAdapter); } } @@ -500,11 +330,64 @@ public final class Reference } else { - return new Reference(instance, identity, facet, mode, secure, - origEndpoints, newEndpoints); + return instance.referenceFactory().create(identity, facet, mode, secure, + origEndpoints, newEndpoints, + routerInfo, reverseAdapter); } } + public Reference + changeRouter(Ice.RouterPrx newRouter) + { + RouterInfo newRouterInfo = instance.routerManager().get(newRouter); + + if (newRouterInfo.equals(routerInfo)) + { + return this; + } + else + { + return instance.referenceFactory().create(identity, facet, mode, secure, + origEndpoints, endpoints, + newRouterInfo, reverseAdapter); + } + } + + public Reference + changeDefault() + { + return instance.referenceFactory().create(identity, "", ModeTwoway, false, + origEndpoints, origEndpoints, + null, null); + } + + // + // Only for use by ReferenceFactory + // + Reference(Instance inst, + Ice.Identity ident, + String fac, + int md, + boolean sec, + Endpoint[] origEndpts, + Endpoint[] endpts, + RouterInfo rtrInfo, + Ice.ObjectAdapter rvAdapter) + { + instance = inst; + identity = ident; + facet = fac; + mode = md; + secure = sec; + origEndpoints = origEndpts; + endpoints = endpts; + routerInfo = rtrInfo; + reverseAdapter = rvAdapter; + hashValue = 0; + + calcHashValue(); + } + private void calcHashValue() { diff --git a/java/src/IceInternal/ReferenceFactory.java b/java/src/IceInternal/ReferenceFactory.java new file mode 100644 index 00000000000..5361da5468b --- /dev/null +++ b/java/src/IceInternal/ReferenceFactory.java @@ -0,0 +1,342 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +package IceInternal; + +public final class ReferenceFactory +{ + public synchronized Reference + create(Ice.Identity ident, + String facet, + int mode, + boolean secure, + Endpoint[] origEndpoints, + Endpoint[] endpoints, + RouterInfo routerInfo, + Ice.ObjectAdapter reverseAdapter) + { + if (_instance == null) + { + throw new Ice.CommunicatorDestroyedException(); + } + + // + // Create a new reference + // + Reference ref = new Reference(_instance, ident, facet, mode, secure, + origEndpoints, endpoints, + routerInfo, reverseAdapter); + + // + // If we already have an equivalent reference, use such equivalent + // reference. Otherwise add the new reference to the reference + // set. + // + // Java implementation note: A WeakHashMap is used to hold References, + // allowing References to be garbage collected automatically. A + // Reference serves as both key and value in the map. The + // WeakHashMap class internally creates a weak reference for the + // key, and we use a weak reference for the value as well. + // + java.lang.ref.WeakReference w = (java.lang.ref.WeakReference)_references.get(ref); + if (w != null) + { + Reference r = (Reference)w.get(); + if (r != null) + { + ref = r; + } + else + { + _references.put(ref, new java.lang.ref.WeakReference(ref)); + } + } + else + { + _references.put(ref, new java.lang.ref.WeakReference(ref)); + } + + return ref; + } + + public Reference + create(String str) + { + String s = str.trim(); + if (s.length() == 0) + { + throw new Ice.ReferenceParseException(); + } + + int colon = s.indexOf(':'); + String init; + if (colon == -1) + { + init = s; + } + else + { + init = s.substring(0, colon); + } + + String[] arr = init.split("[ \t\n\r]+"); + Ice.Identity ident = Ice.Util.stringToIdentity(arr[0]); + String facet = ""; + int mode = Reference.ModeTwoway; + boolean secure = false; + + int i = 1; + while (i < arr.length) + { + String option = arr[i++]; + if (option.length() != 2 || option.charAt(0) != '-') + { + throw new Ice.ReferenceParseException(); + } + + String argument = null; + if (i < arr.length && arr[i].charAt(0) != '-') + { + argument = arr[i++]; + } + + // + // If any new options are added here, + // IceInternal::Reference::toString() must be updated as well. + // + switch (option.charAt(1)) + { + case 'f': + { + if (argument == null) + { + throw new Ice.EndpointParseException(); + } + + facet = argument; + break; + } + + case 't': + { + if (argument != null) + { + throw new Ice.EndpointParseException(); + } + + mode = Reference.ModeTwoway; + break; + } + + case 'o': + { + if (argument != null) + { + throw new Ice.EndpointParseException(); + } + + mode = Reference.ModeOneway; + break; + } + + case 'O': + { + if (argument != null) + { + throw new Ice.EndpointParseException(); + } + + mode = Reference.ModeBatchOneway; + break; + } + + case 'd': + { + if (argument != null) + { + throw new Ice.EndpointParseException(); + } + + mode = Reference.ModeDatagram; + break; + } + + case 'D': + { + if (argument != null) + { + throw new Ice.EndpointParseException(); + } + + mode = Reference.ModeBatchDatagram; + break; + } + + case 's': + { + if (argument != null) + { + throw new Ice.EndpointParseException(); + } + + secure = true; + break; + } + + default: + { + throw new Ice.ReferenceParseException(); + } + } + } + + java.util.ArrayList origEndpoints = new java.util.ArrayList(); + java.util.ArrayList endpoints = new java.util.ArrayList(); + + boolean orig = true; + final int len = s.length(); + int end = colon; + while (end < len && s.charAt(end) == ':') + { + int beg = end + 1; + + end = s.indexOf(':', beg); + if (end == -1) + { + end = len; + } + + if (beg == end) // "::" + { + if (!orig) + { + throw new Ice.ReferenceParseException(); + } + + orig = false; + continue; + } + + String es = s.substring(beg, end); + Endpoint endp = Endpoint.endpointFromString(_instance, es); + + if (orig) + { + origEndpoints.add(endp); + } + else + { + endpoints.add(endp); + } + } + + if (orig) + { + endpoints = origEndpoints; + } + + if (origEndpoints.size() == 0 || endpoints.size() == 0) + { + throw new Ice.ReferenceParseException(); + } + + Endpoint[] origEndp = new Endpoint[origEndpoints.size()]; + origEndpoints.toArray(origEndp); + Endpoint[] endp = new Endpoint[endpoints.size()]; + endpoints.toArray(endp); + + RouterInfo routerInfo = _instance.routerManager().get(getDefaultRouter()); + return create(ident, facet, mode, secure, origEndp, endp, routerInfo, null); + } + + public Reference + create(Ice.Identity ident, BasicStream s) + { + // + // Don't read the identity here. Operations calling this + // constructor read the identity, and pass it as a parameter. + // + + String facet = s.readString(); + + int mode = (int)s.readByte(); + if (mode < 0 || mode > Reference.ModeLast) + { + throw new Ice.ProxyUnmarshalException(); + } + + boolean secure = s.readBool(); + + Endpoint[] origEndpoints; + Endpoint[] endpoints; + + int sz = s.readInt(); + origEndpoints = new Endpoint[sz]; + for (int i = 0; i < sz; i++) + { + origEndpoints[i] = Endpoint.streamRead(s); + } + + boolean same = s.readBool(); + if (same) // origEndpoints == endpoints + { + endpoints = origEndpoints; + } + else + { + sz = s.readInt(); + endpoints = new Endpoint[sz]; + for (int i = 0; i < sz; i++) + { + endpoints[i] = Endpoint.streamRead(s); + } + } + + RouterInfo routerInfo = _instance.routerManager().get(getDefaultRouter()); + return create(ident, facet, mode, secure, origEndpoints, endpoints, routerInfo, null); + } + + public synchronized void + setDefaultRouter(Ice.RouterPrx defaultRouter) + { + _defaultRouter = defaultRouter; + } + + public synchronized Ice.RouterPrx + getDefaultRouter() + { + return _defaultRouter; + } + + // + // Only for use by Instance + // + ReferenceFactory(Instance instance) + { + _instance = instance; + } + + synchronized void + destroy() + { + if (_instance == null) + { + throw new Ice.CommunicatorDestroyedException(); + } + + _instance = null; + _defaultRouter = null; + _references.clear(); + } + + private Instance _instance; + private Ice.RouterPrx _defaultRouter; + private java.util.WeakHashMap _references = new java.util.WeakHashMap(); +} diff --git a/java/src/IceInternal/RouterInfo.java b/java/src/IceInternal/RouterInfo.java new file mode 100644 index 00000000000..fdea6cff332 --- /dev/null +++ b/java/src/IceInternal/RouterInfo.java @@ -0,0 +1,122 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +package IceInternal; + +public final class RouterInfo +{ + RouterInfo(Ice.RouterPrx router) + { + _router = router; + _routingTable = new Ice.RoutingTable(); + + assert(_router != null); + } + + public boolean + equals(java.lang.Object obj) + { + RouterInfo rhs = null; + try + { + rhs = (RouterInfo)obj; + } + catch (ClassCastException ex) + { + return false; + } + + return _router.equals(rhs._router); + } + + public Ice.RouterPrx + getRouter() + { + // + // No mutex lock necessary, _router is immutable. + // + return _router; + } + + public synchronized Ice.ObjectPrx + getClientProxy() + { + if (_clientProxy == null) // Lazy initialization. + { + _clientProxy = _router.getClientProxy(); + if (_clientProxy == null) + { + throw new Ice.NoEndpointException(); + } + _clientProxy = _clientProxy.ice_router(null); // The client proxy cannot be routed. + } + + return _clientProxy; + } + + public synchronized void + setClientProxy(Ice.ObjectPrx clientProxy) + { + _clientProxy = clientProxy.ice_router(null); // The client proxy cannot be routed. + } + + public Ice.ObjectPrx + getServerProxy() + { + if (_serverProxy == null) // Lazy initialization. + { + _serverProxy = _router.getServerProxy(); + if (_serverProxy == null) + { + throw new Ice.NoEndpointException(); + } + _serverProxy = _serverProxy.ice_router(null); // The server proxy cannot be routed. + } + + return _clientProxy; + } + + public void + setServerProxy(Ice.ObjectPrx serverProxy) + { + _serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed. + } + + public void + addProxy(Ice.ObjectPrx proxy) + { + // + // No mutex lock necessary, _routingTable is immutable, and + // RoutingTable is mutex protected. + // + if (_routingTable.add(proxy)) // Only add the proxy to the router if it's not already in the routing table. + { + _router.addProxy(proxy); + } + } + + public synchronized void + setAdapter(Ice.ObjectAdapter adapter) + { + _adapter = adapter; + } + + public synchronized Ice.ObjectAdapter + getAdapter() + { + return _adapter; + } + + private Ice.RouterPrx _router; + private Ice.ObjectPrx _clientProxy; + private Ice.ObjectPrx _serverProxy; + private Ice.RoutingTable _routingTable; + private Ice.ObjectAdapter _adapter; +} diff --git a/java/src/IceInternal/RouterManager.java b/java/src/IceInternal/RouterManager.java new file mode 100644 index 00000000000..5058792565f --- /dev/null +++ b/java/src/IceInternal/RouterManager.java @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +package IceInternal; + +public final class RouterManager +{ + RouterManager() + { + } + + synchronized void + destroy() + { + _table.clear(); + } + + // + // Returns router info for a given router. Automatically creates + // the router info if it doesn't exist yet. + // + public RouterInfo + get(Ice.RouterPrx rtr) + { + if (rtr == null) + { + return null; + } + + Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(rtr.ice_router(null)); // The router cannot be routed. + + synchronized (this) + { + RouterInfo info = (RouterInfo)_table.get(router); + if (info == null) + { + info = new RouterInfo(router); + _table.put(router, info); + } + + return info; + } + } + + private java.util.HashMap _table = new java.util.HashMap(); +} diff --git a/java/src/IceInternal/TcpAcceptor.java b/java/src/IceInternal/TcpAcceptor.java index e36caf7d3c4..6884040ee20 100644 --- a/java/src/IceInternal/TcpAcceptor.java +++ b/java/src/IceInternal/TcpAcceptor.java @@ -99,7 +99,7 @@ class TcpAcceptor implements Acceptor return Network.addrToString(_addr); } - boolean + final boolean equivalent(String host, int port) { java.net.InetSocketAddress addr = Network.getAddress(host, port); diff --git a/java/src/IceInternal/TcpEndpoint.java b/java/src/IceInternal/TcpEndpoint.java index 084ed3bf19f..4664f9f763a 100644 --- a/java/src/IceInternal/TcpEndpoint.java +++ b/java/src/IceInternal/TcpEndpoint.java @@ -34,6 +34,12 @@ public final class TcpEndpoint extends Endpoint int i = 0; while (i < arr.length) { + if (arr[i].length() == 0) + { + i++; + continue; + } + String option = arr[i++]; if (option.length() != 2 || option.charAt(0) != '-') { @@ -141,7 +147,12 @@ public final class TcpEndpoint extends Endpoint public String toString() { - return "tcp -h " + _host + " -p " + _port + " -t " + _timeout; + String s = "tcp -h " + _host + " -p " + _port; + if (_timeout != -1) + { + s += " -t " + _timeout; + } + return s; } // @@ -262,7 +273,6 @@ public final class TcpEndpoint extends Endpoint public boolean equivalent(Acceptor acceptor) { - /* TODO - implement TcpAcceptor tcpAcceptor = null; try { @@ -273,16 +283,20 @@ public final class TcpEndpoint extends Endpoint return false; } return tcpAcceptor.equivalent(_host, _port); - */ - return false; } - + // // Compare endpoints for sorting purposes // public boolean equals(java.lang.Object obj) { + return compareTo(obj) == 0; + } + + public int + compareTo(java.lang.Object obj) // From java.lang.Comparable + { TcpEndpoint p = null; try @@ -291,44 +305,58 @@ public final class TcpEndpoint extends Endpoint } catch (ClassCastException ex) { - return false; + return 1; } if (this == p) { - return true; + return 0; } - if (_port != p._port) + if (_port < p._port) { - return false; + return -1; + } + else if (p._port < _port) + { + return 1; } - if (_timeout != p._timeout) + if (_timeout < p._timeout) { - return false; + return -1; + } + else if (p._timeout < _timeout) + { + return 1; } if (!_host.equals(p._host)) { - try + // + // We do the most time-consuming part of the comparison last. + // + java.net.InetSocketAddress laddr; + java.net.InetSocketAddress raddr; + laddr = Network.getAddress(_host, _port); + raddr = Network.getAddress(p._host, p._port); + byte[] larr = laddr.getAddress().getAddress(); + byte[] rarr = raddr.getAddress().getAddress(); + assert(larr.length == rarr.length); + for (int i = 0; i < larr.length; i++) { - java.net.InetAddress addr1 = - java.net.InetAddress.getByName(_host); - - java.net.InetAddress addr2 = - java.net.InetAddress.getByName(p._host); - - if(!addr1.equals(addr2)) - return false; - } - catch(java.net.UnknownHostException ex) - { - return false; + if (larr[i] < rarr[i]) + { + return -1; + } + else if (rarr[i] < larr[i]) + { + return 1; + } } } - return true; + return 0; } private Instance _instance; diff --git a/java/src/IceInternal/ThreadPool.java b/java/src/IceInternal/ThreadPool.java index e73e01b84b4..de9d99138b8 100644 --- a/java/src/IceInternal/ThreadPool.java +++ b/java/src/IceInternal/ThreadPool.java @@ -179,26 +179,26 @@ public final class ThreadPool } } - try + _threadNum = 10; + value = _instance.properties().getProperty("Ice.ThreadPool.Size"); + if (value != null) { - _threadNum = 10; - value = _instance.properties().getProperty("Ice.ThreadPool.Size"); - if (value != null) + try { - try - { - _threadNum = Integer.parseInt(value); - if (_threadNum < 1) - { - _threadNum = 1; - } - } - catch (NumberFormatException ex) + _threadNum = Integer.parseInt(value); + if (_threadNum < 1) { - // TODO: Error? + _threadNum = 1; } } + catch (NumberFormatException ex) + { + // TODO: Error? + } + } + try + { _threads = new EventHandlerThread[_threadNum]; for (int i = 0; i < _threadNum; i++) { @@ -474,53 +474,50 @@ public final class ThreadPool { BasicStream stream = handler._stream; - if (stream.size() < Protocol.headerSize) // Read header? + if (stream.size() == 0) { - if (stream.size() == 0) - { - stream.resize(Protocol.headerSize, true); - stream.pos(0); - } + stream.resize(Protocol.headerSize, true); + stream.pos(0); + } + if (stream.pos() != stream.size()) + { handler.read(stream); - if (stream.pos() != stream.size()) - { - return; - } + assert(stream.pos() != stream.size()); } - if (stream.size() >= Protocol.headerSize) // Interpret header? + int pos = stream.pos(); + stream.pos(0); + byte protVer = stream.readByte(); + if (protVer != Protocol.protocolVersion) + { + throw new Ice.UnsupportedProtocolException(); + } + byte encVer = stream.readByte(); + if (encVer != Protocol.encodingVersion) + { + throw new Ice.UnsupportedEncodingException(); + } + byte messageType = stream.readByte(); + int size = stream.readInt(); + if (size < Protocol.headerSize) + { + throw new Ice.IllegalMessageSizeException(); + } + if (size > 1024 * 1024) // TODO: Configurable + { + throw new Ice.MemoryLimitException(); + } + if (size > stream.size()) { - int pos = stream.pos(); - stream.pos(0); - byte protVer = stream.readByte(); - if (protVer != Protocol.protocolVersion) - { - throw new Ice.UnsupportedProtocolException(); - } - byte encVer = stream.readByte(); - if (encVer != Protocol.encodingVersion) - { - throw new Ice.UnsupportedEncodingException(); - } - byte messageType = stream.readByte(); - int size = stream.readInt(); - if (size < Protocol.headerSize) - { - throw new Ice.IllegalMessageSizeException(); - } - if (size > 1024 * 1024) // TODO: Configurable - { - throw new Ice.MemoryLimitException(); - } stream.resize(size, true); - stream.pos(pos); } + stream.pos(pos); - if (stream.size() > Protocol.headerSize && - stream.pos() != stream.size()) + if (stream.pos() != stream.size()) { handler.read(stream); + assert(stream.pos() != stream.size()); } } diff --git a/java/src/IceInternal/TraceUtil.java b/java/src/IceInternal/TraceUtil.java index af57b9381a4..eca333cd055 100644 --- a/java/src/IceInternal/TraceUtil.java +++ b/java/src/IceInternal/TraceUtil.java @@ -229,25 +229,10 @@ final class TraceUtil { try { - Ice.Identity identity = null; - String facet = null; - boolean gotProxy = stream.readBool(); - out.write("\naddressing = " + gotProxy); - if (gotProxy) - { - out.write(" (proxy)"); - Ice.ObjectPrx proxy = stream.readProxy(); - identity = proxy.ice_getIdentity(); - facet = proxy.ice_getFacet(); - } - else - { - out.write(" (identity)"); - identity = new Ice.Identity(); - identity.__read(stream); - facet = stream.readString(); - } + Ice.Identity identity = new Ice.Identity(); + identity.__read(stream); out.write("\nidentity = " + Ice.Util.identityToString(identity)); + String facet = stream.readString(); out.write("\nfacet = " + facet); String operation = stream.readString(); out.write("\noperation = " + operation); diff --git a/java/src/IceInternal/UdpEndpoint.java b/java/src/IceInternal/UdpEndpoint.java index de27d9b191b..cc6b5ac8b59 100644 --- a/java/src/IceInternal/UdpEndpoint.java +++ b/java/src/IceInternal/UdpEndpoint.java @@ -18,6 +18,7 @@ public final class UdpEndpoint extends Endpoint _instance = instance; _host = ho; _port = po; + _connect = false; } public @@ -26,12 +27,19 @@ public final class UdpEndpoint extends Endpoint _instance = instance; _host = null; _port = 0; + _connect = false; String[] arr = str.split("[ \t\n\r]+"); int i = 0; while (i < arr.length) { + if (arr[i].length() == 0) + { + i++; + continue; + } + String option = arr[i++]; if (option.length() != 2 || option.charAt(0) != '-') { @@ -76,6 +84,17 @@ public final class UdpEndpoint extends Endpoint break; } + case 'c': + { + if (argument != null) + { + throw new Ice.EndpointParseException(); + } + + _connect = true; + break; + } + default: { throw new Ice.EndpointParseException(); @@ -96,6 +115,9 @@ public final class UdpEndpoint extends Endpoint s.startReadEncaps(); _host = s.readString(); _port = s.readInt(); + // Not transmitted. + //_connect = s.readBool(); + _connect = false; s.endReadEncaps(); } @@ -109,6 +131,8 @@ public final class UdpEndpoint extends Endpoint s.startWriteEncaps(); s.writeString(_host); s.writeInt(_port); + // Not transmitted. + //s.writeBool(_connect); s.endWriteEncaps(); } @@ -118,7 +142,12 @@ public final class UdpEndpoint extends Endpoint public String toString() { - return "udp -h " + _host + " -p " + _port; + String s = "udp -h " + _host + " -p " + _port; + if (_connect) + { + s += " -c"; + } + return s; } // @@ -189,7 +218,7 @@ public final class UdpEndpoint extends Endpoint public Transceiver serverTransceiver(EndpointHolder endpoint) { - UdpTransceiver p = new UdpTransceiver(_instance, _port); + UdpTransceiver p = new UdpTransceiver(_instance, _port, _connect); endpoint.value = new UdpEndpoint(_instance, _host, p.effectivePort()); return p; } @@ -249,6 +278,12 @@ public final class UdpEndpoint extends Endpoint public boolean equals(java.lang.Object obj) { + return compareTo(obj) == 0; + } + + public int + compareTo(java.lang.Object obj) // From java.lang.Comparable + { UdpEndpoint p = null; try @@ -257,42 +292,62 @@ public final class UdpEndpoint extends Endpoint } catch (ClassCastException ex) { - return false; + return 1; } if (this == p) { - return true; + return 0; } - if (_port != p._port) + if (_port < p._port) { - return false; + return -1; } - - if (!_host.equals(p._host)) + else if (p._port < _port) { - try - { - java.net.InetAddress addr1 = - java.net.InetAddress.getByName(_host); + return 1; + } - java.net.InetAddress addr2 = - java.net.InetAddress.getByName(p._host); + if (!_connect && p._connect) + { + return -1; + } + else if (!p._connect && _connect) + { + return 1; + } - if(!addr1.equals(addr2)) - return false; - } - catch(java.net.UnknownHostException ex) + if (!_host.equals(p._host)) + { + // + // We do the most time-consuming part of the comparison last. + // + java.net.InetSocketAddress laddr; + java.net.InetSocketAddress raddr; + laddr = Network.getAddress(_host, _port); + raddr = Network.getAddress(p._host, p._port); + byte[] larr = laddr.getAddress().getAddress(); + byte[] rarr = raddr.getAddress().getAddress(); + assert(larr.length == rarr.length); + for (int i = 0; i < larr.length; i++) { - return false; + if (larr[i] < rarr[i]) + { + return -1; + } + else if (rarr[i] < larr[i]) + { + return 1; + } } } - return true; + return 0; } private Instance _instance; private String _host; private int _port; + private boolean _connect; } diff --git a/java/src/IceInternal/UdpTransceiver.java b/java/src/IceInternal/UdpTransceiver.java index e451b7b9bb1..0fc3f9f227a 100644 --- a/java/src/IceInternal/UdpTransceiver.java +++ b/java/src/IceInternal/UdpTransceiver.java @@ -23,15 +23,7 @@ final class UdpTransceiver implements Transceiver { if (_traceLevels.network >= 1) { - String s; - if (_sender) - { - s = "stopping to send udp packets to " + toString(); - } - else - { - s = "stopping to receive udp packets at " + toString(); - } + String s = "closing udp connection\n" + toString(); _logger.trace(_traceLevels.networkCat, s); } @@ -57,7 +49,6 @@ final class UdpTransceiver implements Transceiver { java.nio.ByteBuffer buf = stream.prepareWrite(); - assert(_sender); assert(buf.position() == 0); final int packetSize = 64 * 1024; // TODO: configurable assert(packetSize >= buf.limit()); // TODO: exception @@ -70,8 +61,7 @@ final class UdpTransceiver implements Transceiver if (_traceLevels.network >= 3) { - String s = "sent " + ret + " bytes via udp to " + - toString(); + String s = "sent " + ret + " bytes via " + _protocolName + "\n" + toString(); _logger.trace(_traceLevels.networkCat, s); } @@ -94,57 +84,87 @@ final class UdpTransceiver implements Transceiver public void read(BasicStream stream, int timeout) { - assert(!_sender); assert(stream.pos() == 0); final int packetSize = 64 * 1024; // TODO: configurable stream.resize(packetSize, true); - java.nio.ByteBuffer buf = stream.prepareRead(); buf.position(0); + + int ret = 0; while (true) { - try + if (_connect) { - java.net.SocketAddress source = _fd.receive(buf); - int tot = buf.position(); + // + // If we must connect, then we connect to the first peer that + // sends us a packet. + // + try + { + java.net.InetSocketAddress peerAddr = (java.net.InetSocketAddress)_fd.receive(buf); + ret = buf.position(); + Network.doConnect(_fd, peerAddr, -1); + _connect = false; // We're connected now - if (_traceLevels.network >= 3) + if (_traceLevels.network >= 1) + { + String s = "connected " + _protocolName + "socket\n" + toString(); + _logger.trace(_traceLevels.networkCat, s); + } + } + catch (java.io.InterruptedIOException ex) { - String s = "received " + tot + " bytes via udp at " + - toString(); - _logger.trace(_traceLevels.networkCat, s); + continue; + } + catch (java.io.IOException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; } - - stream.resize(tot, true); - stream.pos(tot); - break; - } - catch (java.io.InterruptedIOException ex) - { - continue; } - catch (java.io.IOException ex) + else { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; + try + { + _fd.receive(buf); + ret = buf.position(); + } + catch (java.io.InterruptedIOException ex) + { + continue; + } + catch (java.io.IOException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } } + + break; + } + + if (_traceLevels.network >= 3) + { + String s = "received " + ret + " bytes via " + _protocolName + "\n" + toString(); + _logger.trace(_traceLevels.networkCat, s); } + + stream.resize(ret, true); + stream.pos(ret); } public String toString() { - return Network.addrToString(_addr); + return Network.fdToString(_fd); } - public boolean + public final boolean equivalent(String host, int port) { - if (_sender) - { - return false; - } + assert(_incoming); // This equivalence test is only valid for incoming connections. java.net.InetSocketAddress addr = Network.getAddress(host, port); if (addr.getAddress().isLoopbackAddress()) @@ -163,25 +183,47 @@ final class UdpTransceiver implements Transceiver return _addr.getPort(); } + public final void + setProtocolName(String protocolName) + { + _protocolName = protocolName; + } + + // + // Only for use by UdpEndpoint + // + UdpTransceiver(Instance instance, + String host, + int port) + { + this(instance, host, port, "udp"); + } + // // Only for use by UdpEndpoint // - UdpTransceiver(Instance instance, String host, int port) + UdpTransceiver(Instance instance, + String host, + int port, + String protocolName) { _instance = instance; _traceLevels = instance.traceLevels(); _logger = instance.logger(); - _sender = true; + _incoming = false; + _connect = true; + _protocolName = protocolName; try { _addr = Network.getAddress(host, port); _fd = Network.createUdpSocket(); Network.doConnect(_fd, _addr, -1); + _connect = false; // We're connected now if (_traceLevels.network >= 1) { - String s = "starting to send udp packets to " + toString(); + String s = "starting to send " + _protocolName + " packets\n" + toString(); _logger.trace(_traceLevels.networkCat, s); } } @@ -195,12 +237,27 @@ final class UdpTransceiver implements Transceiver // // Only for use by UdpEndpoint // - UdpTransceiver(Instance instance, int port) + UdpTransceiver(Instance instance, + int port, + boolean connect) + { + this(instance, port, connect, "udp"); + } + + // + // Only for use by UdpEndpoint + // + UdpTransceiver(Instance instance, + int port, + boolean connect, + String protocolName) { _instance = instance; _traceLevels = instance.traceLevels(); _logger = instance.logger(); - _sender = false; + _incoming = true; + _connect = connect; + _protocolName = protocolName; try { @@ -210,7 +267,7 @@ final class UdpTransceiver implements Transceiver if (_traceLevels.network >= 1) { - String s = "starting to receive udp packets at " + toString(); + String s = "starting to receive " + _protocolName + " packets\n" + toString(); _logger.trace(_traceLevels.networkCat, s); } } @@ -232,7 +289,9 @@ final class UdpTransceiver implements Transceiver private Instance _instance; private TraceLevels _traceLevels; private Ice.Logger _logger; - private boolean _sender; + private boolean _incoming; + private boolean _connect; private java.nio.channels.DatagramChannel _fd; private java.net.InetSocketAddress _addr; + private String _protocolName; } diff --git a/java/src/IceInternal/UnknownEndpoint.java b/java/src/IceInternal/UnknownEndpoint.java index 95eb8369774..ec96847a3f0 100644 --- a/java/src/IceInternal/UnknownEndpoint.java +++ b/java/src/IceInternal/UnknownEndpoint.java @@ -156,6 +156,12 @@ public final class UnknownEndpoint extends Endpoint public boolean equals(java.lang.Object obj) { + return compareTo(obj) == 0; + } + + public int + compareTo(java.lang.Object obj) // From java.lang.Comparable + { UnknownEndpoint p = null; try @@ -164,20 +170,35 @@ public final class UnknownEndpoint extends Endpoint } catch (ClassCastException ex) { - return false; + return 1; } if (this == p) { - return true; + return 0; } - if (!java.util.Arrays.equals(_rawBytes, p._rawBytes)) + if (_rawBytes.length < p._rawBytes.length) + { + return -1; + } + else if (p._rawBytes.length < _rawBytes.length) + { + return 1; + } + for (int i = 0; i < _rawBytes.length; i++) { - return false; + if (_rawBytes[i] < p._rawBytes[i]) + { + return -1; + } + else if (p._rawBytes[i] < _rawBytes[i]) + { + return 1; + } } - return true; + return 0; } private Instance _instance; |