diff options
24 files changed, 1504 insertions, 1365 deletions
diff --git a/javae/src/Ice/ConnectionI.java b/javae/src/Ice/ConnectionI.java index a00ab34a602..584dd2c447c 100644 --- a/javae/src/Ice/ConnectionI.java +++ b/javae/src/Ice/ConnectionI.java @@ -86,24 +86,33 @@ public final class ConnectionI implements Connection if(active) { - IceInternal.BasicStream os = new IceInternal.BasicStream(_instance); - os.writeBlob(IceInternal.Protocol.magic); - os.writeByte(IceInternal.Protocol.protocolMajor); - os.writeByte(IceInternal.Protocol.protocolMinor); - os.writeByte(IceInternal.Protocol.encodingMajor); - os.writeByte(IceInternal.Protocol.encodingMinor); - os.writeByte(IceInternal.Protocol.validateConnectionMsg); - os.writeByte((byte)0); // Compression status (always zero for validate connection). - os.writeInt(IceInternal.Protocol.headerSize); // Message size. - IceInternal.TraceUtil.traceHeader("sending validate connection", os, _logger, _traceLevels); - try - { - _transceiver.write(os, timeout); - } - catch(Ice.TimeoutException ex) - { - throw new Ice.ConnectTimeoutException(); - } + synchronized(_sendMutex) + { + if(_transceiver == null) // Has the transceiver already been closed? + { + assert(_exception != null); + throw _exception; // The exception is immutable at this point. + } + + IceInternal.BasicStream os = new IceInternal.BasicStream(_instance); + os.writeBlob(IceInternal.Protocol.magic); + os.writeByte(IceInternal.Protocol.protocolMajor); + os.writeByte(IceInternal.Protocol.protocolMinor); + os.writeByte(IceInternal.Protocol.encodingMajor); + os.writeByte(IceInternal.Protocol.encodingMinor); + os.writeByte(IceInternal.Protocol.validateConnectionMsg); + os.writeByte((byte)0); // Compression status (always zero for validate connection). + os.writeInt(IceInternal.Protocol.headerSize); // Message size. + IceInternal.TraceUtil.traceHeader("sending validate connection", os, _logger, _traceLevels); + try + { + _transceiver.write(os, timeout); + } + catch(Ice.TimeoutException ex) + { + throw new Ice.ConnectTimeoutException(); + } + } } else { @@ -254,21 +263,6 @@ public final class ConnectionI implements Connection threadPerConnection = _threadPerConnection; _threadPerConnection = null; - - // - // We must destroy the incoming cache. It is now not - // needed anymore. - // - synchronized(_incomingCacheMutex) - { - while(_incomingCache != null) - { - _incomingCache.__destroy(); - _incomingCache = _incomingCache.next; - } - } - - cleanup(); } if(threadPerConnection != null) @@ -382,21 +376,6 @@ public final class ConnectionI implements Connection threadPerConnection = _threadPerConnection; _threadPerConnection = null; - - // - // We must destroy the incoming cache. It is now not - // needed anymore. - // - synchronized(_incomingCacheMutex) - { - while(_incomingCache != null) - { - _incomingCache.__destroy(); - _incomingCache = _incomingCache.next; - } - } - - cleanup(); } if(threadPerConnection != null) @@ -635,10 +614,9 @@ public final class ConnectionI implements Connection { // // Destroy and reset the batch stream and batch count. We - // cannot safe old requests in the batch stream, as they might + // cannot save old requests in the batch stream, as they might // be corrupted due to incomplete marshaling. // - _batchStream.destroy(); _batchStream = new IceInternal.BasicStream(_instance); _batchRequestNum = 0; @@ -740,7 +718,6 @@ public final class ConnectionI implements Connection // // Reset the batch stream, and notify that flushing is over. // - _batchStream.destroy(); _batchStream = new IceInternal.BasicStream(_instance); _batchRequestNum = 0; _batchStreamInUse = false; @@ -1016,7 +993,6 @@ public final class ConnectionI implements Connection IceUtil.Assert.FinalizerAssert(_transceiver == null); IceUtil.Assert.FinalizerAssert(_dispatchCount == 0); IceUtil.Assert.FinalizerAssert(_threadPerConnection == null); - IceUtil.Assert.FinalizerAssert(_incomingCache == null); } private static final int StateNotValidated = 0; @@ -1076,6 +1052,14 @@ public final class ConnectionI implements Connection private void setState(int state) { + // + // Skip graceful shutdown if we are destroyed before validation. + // + if(_state == StateNotValidated && state == StateClosing) + { + state = StateClosed; + } + if(_state == state) // Don't switch twice. { return; @@ -1132,7 +1116,7 @@ public final class ConnectionI implements Connection // // If we are in thread per connection mode, we // shutdown both for reading and writing. This will - // unblock and read call with an exception. The thread + // unblock any read call with an exception. The thread // per connection then closes the transceiver. // _transceiver.shutdownReadWrite(); @@ -1205,7 +1189,6 @@ public final class ConnectionI implements Connection } IceInternal.BasicStream stream; - boolean destroyStream; int invokeNum; int requestId; IceInternal.ServantManager servantManager; @@ -1327,12 +1310,6 @@ public final class ConnectionI implements Connection catch(LocalException ex) { setState(StateClosed, ex); - - if(info.destroyStream) - { - info.stream.destroy(); - info.destroyStream = false; - } } } @@ -1470,7 +1447,7 @@ public final class ConnectionI implements Connection { // // The thread-per-connection must validate and activate this connection, - // and not in the // connection factory. Please see the comments in the + // and not in the connection factory. Please see the comments in the // connection factory for details. // try @@ -1509,6 +1486,8 @@ public final class ConnectionI implements Connection boolean closed = false; + IceInternal.BasicStream stream = new IceInternal.BasicStream(_instance); + while(!closed) { // @@ -1516,83 +1495,81 @@ public final class ConnectionI implements Connection // synchronization, because we use blocking accept. // - IceInternal.BasicStream stream = new IceInternal.BasicStream(_instance); - try { - stream.resize(IceInternal.Protocol.headerSize, true); - stream.pos(0); - _transceiver.read(stream, -1); - - int pos = stream.pos(); - assert(pos >= IceInternal.Protocol.headerSize); - stream.pos(0); - byte[] m = stream.readBlob(4); - if(m[0] != IceInternal.Protocol.magic[0] || m[1] != IceInternal.Protocol.magic[1] || - m[2] != IceInternal.Protocol.magic[2] || m[3] != IceInternal.Protocol.magic[3]) - { - BadMagicException ex = new BadMagicException(); - ex.badMagic = m; - throw ex; - } - byte pMajor = stream.readByte(); - byte pMinor = stream.readByte(); - if(pMajor != IceInternal.Protocol.protocolMajor) - { - UnsupportedProtocolException e = new UnsupportedProtocolException(); - e.badMajor = pMajor < 0 ? pMajor + 255 : pMajor; - e.badMinor = pMinor < 0 ? pMinor + 255 : pMinor; - e.major = IceInternal.Protocol.protocolMajor; - e.minor = IceInternal.Protocol.protocolMinor; - throw e; - } - byte eMajor = stream.readByte(); - byte eMinor = stream.readByte(); - if(eMajor != IceInternal.Protocol.encodingMajor) - { - UnsupportedEncodingException e = new UnsupportedEncodingException(); - e.badMajor = eMajor < 0 ? eMajor + 255 : eMajor; - e.badMinor = eMinor < 0 ? eMinor + 255 : eMinor; - e.major = IceInternal.Protocol.encodingMajor; - e.minor = IceInternal.Protocol.encodingMinor; - throw e; - } - byte messageType = stream.readByte(); - byte compress = stream.readByte(); - int size = stream.readInt(); - if(size < IceInternal.Protocol.headerSize) - { - throw new IllegalMessageSizeException(); - } - if(size > _instance.messageSizeMax()) - { - throw new MemoryLimitException(); - } - if(size > stream.size()) + try { - stream.resize(size, true); - } - stream.pos(pos); + stream.resize(IceInternal.Protocol.headerSize, true); + stream.pos(0); + _transceiver.read(stream, -1); + + int pos = stream.pos(); + assert(pos >= IceInternal.Protocol.headerSize); + stream.pos(0); + byte[] m = stream.readBlob(4); + if(m[0] != IceInternal.Protocol.magic[0] || m[1] != IceInternal.Protocol.magic[1] || + m[2] != IceInternal.Protocol.magic[2] || m[3] != IceInternal.Protocol.magic[3]) + { + BadMagicException ex = new BadMagicException(); + ex.badMagic = m; + throw ex; + } + byte pMajor = stream.readByte(); + byte pMinor = stream.readByte(); + if(pMajor != IceInternal.Protocol.protocolMajor) + { + UnsupportedProtocolException e = new UnsupportedProtocolException(); + e.badMajor = pMajor < 0 ? pMajor + 255 : pMajor; + e.badMinor = pMinor < 0 ? pMinor + 255 : pMinor; + e.major = IceInternal.Protocol.protocolMajor; + e.minor = IceInternal.Protocol.protocolMinor; + throw e; + } + byte eMajor = stream.readByte(); + byte eMinor = stream.readByte(); + if(eMajor != IceInternal.Protocol.encodingMajor) + { + UnsupportedEncodingException e = new UnsupportedEncodingException(); + e.badMajor = eMajor < 0 ? eMajor + 255 : eMajor; + e.badMinor = eMinor < 0 ? eMinor + 255 : eMinor; + e.major = IceInternal.Protocol.encodingMajor; + e.minor = IceInternal.Protocol.encodingMinor; + throw e; + } + byte messageType = stream.readByte(); + byte compress = stream.readByte(); + int size = stream.readInt(); + if(size < IceInternal.Protocol.headerSize) + { + throw new IllegalMessageSizeException(); + } + if(size > _instance.messageSizeMax()) + { + throw new MemoryLimitException(); + } + if(size > stream.size()) + { + stream.resize(size, true); + } + stream.pos(pos); - if(pos != stream.size()) + if(pos != stream.size()) + { + _transceiver.read(stream, -1); + assert(stream.pos() == stream.size()); + } + } + catch(LocalException ex) { - _transceiver.read(stream, -1); - assert(stream.pos() == stream.size()); + exception(ex); } - } - catch(LocalException ex) - { - exception(ex); - } - MessageInfo info = new MessageInfo(stream); + MessageInfo info = new MessageInfo(stream); - LocalException exception = null; + LocalException exception = null; - IceInternal.IntMap requests = null; + IceInternal.IntMap requests = null; - try - { synchronized(this) { while(_state == StateHolding) @@ -1656,8 +1633,7 @@ public final class ConnectionI implements Connection // must be done outside the thread synchronization, so that nested // calls are possible. // - invokeAll(info.stream, info.invokeNum, info.requestId, info.servantManager, - info.adapter); + invokeAll(info.stream, info.invokeNum, info.requestId, info.servantManager, info.adapter); if(requests != null) { @@ -1674,14 +1650,11 @@ public final class ConnectionI implements Connection { assert(closed); throw exception; - } + } } finally { - if(info.destroyStream) - { - info.stream.destroy(); - } + stream.reset(); } } } @@ -1741,20 +1714,6 @@ public final class ConnectionI implements Connection } } - private void - cleanup() - { - // - // This should be called when we know that this object is no longer used, - // so it is safe to reclaim resources. - // - // We do this here instead of in a finalizer because a C# finalizer - // cannot invoke methods on other types of objects. - // - _batchStream.destroy(); - _batchStream = null; - } - private class ThreadPerConnection extends Thread { public void diff --git a/javae/src/Ice/Object.java b/javae/src/Ice/Object.java index 0c1e9cc11ba..98fd033ce3c 100644 --- a/javae/src/Ice/Object.java +++ b/javae/src/Ice/Object.java @@ -33,7 +33,4 @@ public interface Object void ice_postUnmarshal(); IceInternal.DispatchStatus __dispatch(IceInternal.Incoming in, Current current); - - void __write(IceInternal.BasicStream __os); - void __read(IceInternal.BasicStream __is, boolean __rid); } diff --git a/javae/src/Ice/ObjectAdapterI.java b/javae/src/Ice/ObjectAdapterI.java index ba08b4729b1..908db95e53e 100644 --- a/javae/src/Ice/ObjectAdapterI.java +++ b/javae/src/Ice/ObjectAdapterI.java @@ -200,12 +200,15 @@ public final class ObjectAdapterI extends LocalObjectImpl implements ObjectAdapt // Now we wait for until all incoming connection factories are // finished. // - final int sz = _incomingConnectionFactories.size(); - for(int i = 0; i < sz; ++i) + if(_incomingConnectionFactories != null) { - IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(i); - factory.waitUntilFinished(); + final int sz = _incomingConnectionFactories.size(); + for(int i = 0; i < sz; ++i) + { + IceInternal.IncomingConnectionFactory factory = + (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(i); + factory.waitUntilFinished(); + } } // @@ -229,7 +232,7 @@ public final class ObjectAdapterI extends LocalObjectImpl implements ObjectAdapt // We're done, now we can throw away all incoming connection // factories. // - _incomingConnectionFactories.clear(); + _incomingConnectionFactories = null; // // Remove object references (some of them cyclic). @@ -635,11 +638,22 @@ public final class ObjectAdapterI extends LocalObjectImpl implements ObjectAdapt finalize() throws Throwable { - assert(_servantManager == null); - assert(_communicator == null); - assert(_incomingConnectionFactories != null); - assert(_directCount == 0); - assert(!_waitForDeactivate); + if(!_deactivated) + { + _instance.logger().warning("object adapter `" + _name + "' has not been deactivated"); + } + else if(_instance != null) + { + _instance.logger().warning("object adapter `" + _name + "' deactivation had not been waited for"); + } + else + { + IceUtil.Assert.FinalizerAssert(_servantManager == null); + IceUtil.Assert.FinalizerAssert(_communicator == null); + IceUtil.Assert.FinalizerAssert(_incomingConnectionFactories == null); + IceUtil.Assert.FinalizerAssert(_directCount == 0); + IceUtil.Assert.FinalizerAssert(!_waitForDeactivate); + } super.finalize(); } diff --git a/javae/src/Ice/ObjectImpl.java b/javae/src/Ice/ObjectImpl.java index bd821499d15..8d5347523b2 100644 --- a/javae/src/Ice/ObjectImpl.java +++ b/javae/src/Ice/ObjectImpl.java @@ -174,33 +174,4 @@ public class ObjectImpl implements Object, java.lang.Cloneable assert(false); return IceInternal.DispatchStatus.DispatchOperationNotExist; } - - public void - __write(IceInternal.BasicStream __os) - { - __os.writeTypeId(ice_staticId()); - __os.startWriteSlice(); - __os.writeSize(0); // For compatibility with the old AFM. - __os.endWriteSlice(); - } - - public void - __read(IceInternal.BasicStream __is, boolean __rid) - { - if(__rid) - { - String myId = __is.readTypeId(); - } - - __is.startReadSlice(); - - // For compatibility with the old AFM. - int sz = __is.readSize(); - if(sz != 0) - { - throw new MarshalException(); - } - - __is.endReadSlice(); - } } diff --git a/javae/src/Ice/_ObjectDel.java b/javae/src/Ice/_ObjectDel.java index d7b79630670..f5507b19715 100644 --- a/javae/src/Ice/_ObjectDel.java +++ b/javae/src/Ice/_ObjectDel.java @@ -15,13 +15,13 @@ public class _ObjectDel ice_isA(String __id, java.util.Map __context) throws IceInternal.NonRepeatable { - IceInternal.Outgoing __outS = getOutgoing("ice_isA", OperationMode.Nonmutating, __context); + IceInternal.Outgoing __og = getOutgoing("ice_isA", OperationMode.Nonmutating, __context); try { - IceInternal.BasicStream __is = __outS.is(); - IceInternal.BasicStream __os = __outS.os(); + IceInternal.BasicStream __is = __og.is(); + IceInternal.BasicStream __os = __og.os(); __os.writeString(__id); - if(!__outS.invoke()) + if(!__og.invoke()) { throw new UnknownUserException(); } @@ -36,7 +36,7 @@ public class _ObjectDel } finally { - reclaimOutgoing(__outS); + reclaimOutgoing(__og); } } @@ -44,17 +44,17 @@ public class _ObjectDel ice_ping(java.util.Map __context) throws IceInternal.NonRepeatable { - IceInternal.Outgoing __outS = getOutgoing("ice_ping", OperationMode.Nonmutating, __context); + IceInternal.Outgoing __og = getOutgoing("ice_ping", OperationMode.Nonmutating, __context); try { - if(!__outS.invoke()) + if(!__og.invoke()) { throw new UnknownUserException(); } } finally { - reclaimOutgoing(__outS); + reclaimOutgoing(__og); } } @@ -62,11 +62,11 @@ public class _ObjectDel ice_ids(java.util.Map __context) throws IceInternal.NonRepeatable { - IceInternal.Outgoing __outS = getOutgoing("ice_ids", OperationMode.Nonmutating, __context); + IceInternal.Outgoing __og = getOutgoing("ice_ids", OperationMode.Nonmutating, __context); try { - IceInternal.BasicStream __is = __outS.is(); - if(!__outS.invoke()) + IceInternal.BasicStream __is = __og.is(); + if(!__og.invoke()) { throw new UnknownUserException(); } @@ -81,7 +81,7 @@ public class _ObjectDel } finally { - reclaimOutgoing(__outS); + reclaimOutgoing(__og); } } @@ -89,11 +89,11 @@ public class _ObjectDel ice_id(java.util.Map __context) throws IceInternal.NonRepeatable { - IceInternal.Outgoing __outS = getOutgoing("ice_id", OperationMode.Nonmutating, __context); + IceInternal.Outgoing __og = getOutgoing("ice_id", OperationMode.Nonmutating, __context); try { - IceInternal.BasicStream __is = __outS.is(); - if(!__outS.invoke()) + IceInternal.BasicStream __is = __og.is(); + if(!__og.invoke()) { throw new UnknownUserException(); } @@ -108,7 +108,7 @@ public class _ObjectDel } finally { - reclaimOutgoing(__outS); + reclaimOutgoing(__og); } } @@ -116,20 +116,20 @@ public class _ObjectDel ice_invoke(String operation, OperationMode mode, byte[] inParams, ByteSeqHolder outParams, java.util.Map __context) throws IceInternal.NonRepeatable { - IceInternal.Outgoing __outS = getOutgoing(operation, mode, __context); + IceInternal.Outgoing __og = getOutgoing(operation, mode, __context); try { if(inParams != null) { - IceInternal.BasicStream __os = __outS.os(); + IceInternal.BasicStream __os = __og.os(); __os.writeBlob(inParams); } - boolean ok = __outS.invoke(); + boolean ok = __og.invoke(); if(__reference.getMode() == IceInternal.Reference.ModeTwoway) { try { - IceInternal.BasicStream __is = __outS.is(); + IceInternal.BasicStream __is = __og.is(); int sz = __is.getReadEncapsSize(); if(outParams != null) { @@ -145,7 +145,7 @@ public class _ObjectDel } finally { - reclaimOutgoing(__outS); + reclaimOutgoing(__og); } } @@ -212,6 +212,7 @@ public class _ObjectDel out = __outgoingCache; __outgoingCache = __outgoingCache.next; out.reset(operation, mode, context); + out.next = null; } } @@ -228,19 +229,6 @@ public class _ObjectDel } } - protected void - finalize() - throws Throwable - { - while(__outgoingCache != null) - { - IceInternal.Outgoing next = __outgoingCache.next; - __outgoingCache.destroy(); - __outgoingCache.next = null; - __outgoingCache = next; - } - } - private IceInternal.Outgoing __outgoingCache; private java.lang.Object __outgoingMutex = new java.lang.Object(); } diff --git a/javae/src/IceInternal/Acceptor.java b/javae/src/IceInternal/Acceptor.java index 167d555c7be..55a6f2aca65 100644 --- a/javae/src/IceInternal/Acceptor.java +++ b/javae/src/IceInternal/Acceptor.java @@ -11,7 +11,6 @@ package IceInternal; public interface Acceptor { - java.nio.channels.ServerSocketChannel fd(); void close(); void listen(); Transceiver accept(int timeout); diff --git a/javae/src/IceInternal/BasicStream.java b/javae/src/IceInternal/BasicStream.java index 3a8b7156c90..c56d201874c 100644 --- a/javae/src/IceInternal/BasicStream.java +++ b/javae/src/IceInternal/BasicStream.java @@ -15,41 +15,21 @@ public class BasicStream BasicStream(IceInternal.Instance instance) { _instance = instance; - _bufferManager = instance.bufferManager(); - _buf = _bufferManager.allocate(1500); - assert(_buf != null); + allocate(1500); _capacity = _buf.capacity(); _limit = 0; assert(_buf.limit() == _capacity); _readEncapsStack = null; _writeEncapsStack = null; - _readEncapsCache = null; - _writeEncapsCache = null; - - _sliceObjects = true; _messageSizeMax = _instance.messageSizeMax(); // Cached for efficiency. _seqDataStack = null; - _objectList = null; } // - // Do NOT use a finalizer, this would cause a severe performance - // penalty! We must make sure that destroy() is called instead, to - // reclaim resources. - // - public void - destroy() - { - _bufferManager.reclaim(_buf); - _buf = null; - } - - // - // This function allows this object to be reused, rather than - // reallocated. + // This function allows this object to be reused, rather than reallocated. // public void reset() @@ -58,18 +38,7 @@ public class BasicStream _buf.limit(_capacity); _buf.position(0); - if(_readEncapsStack != null) - { - assert(_readEncapsStack.next == null); - _readEncapsStack.next = _readEncapsCache; - _readEncapsCache = _readEncapsStack; - _readEncapsStack = null; - } - - if(_objectList != null) - { - _objectList.clear(); - } + _readEncapsStack = null; } public IceInternal.Instance @@ -83,7 +52,7 @@ public class BasicStream { assert(_instance == other._instance); - java.nio.ByteBuffer tmpBuf = other._buf; + ByteBuffer tmpBuf = other._buf; other._buf = _buf; _buf = tmpBuf; @@ -99,18 +68,10 @@ public class BasicStream other._readEncapsStack = _readEncapsStack; _readEncapsStack = tmpRead; - tmpRead = other._readEncapsCache; - other._readEncapsCache = _readEncapsCache; - _readEncapsCache = tmpRead; - WriteEncaps tmpWrite = other._writeEncapsStack; other._writeEncapsStack = _writeEncapsStack; _writeEncapsStack = tmpWrite; - tmpWrite = other._writeEncapsCache; - other._writeEncapsCache = _writeEncapsCache; - _writeEncapsCache = tmpWrite; - int tmpReadSlice = other._readSlice; other._readSlice = _readSlice; _readSlice = tmpReadSlice; @@ -122,10 +83,6 @@ public class BasicStream SeqData tmpSeqDataStack = other._seqDataStack; other._seqDataStack = _seqDataStack; _seqDataStack = tmpSeqDataStack; - - java.util.ArrayList tmpObjectList = other._objectList; - other._objectList = _objectList; - _objectList = tmpObjectList; } public void @@ -140,9 +97,7 @@ public class BasicStream final int cap2 = _capacity << 1; int newCapacity = cap2 > total ? cap2 : total; _buf.limit(_limit); - _buf.position(0); - _buf = _bufferManager.reallocate(_buf, newCapacity); - assert(_buf != null); + reallocate(newCapacity); _capacity = _buf.capacity(); } // @@ -163,13 +118,13 @@ public class BasicStream _limit = total; } - public java.nio.ByteBuffer + public ByteBuffer prepareRead() { return _buf; } - public java.nio.ByteBuffer + public ByteBuffer prepareWrite() { _buf.limit(_limit); @@ -331,27 +286,9 @@ public class BasicStream public void startWriteEncaps() { - { - WriteEncaps curr = _writeEncapsCache; - if(curr != null) - { - if(curr.toBeMarshaledMap != null) - { - curr.writeIndex = 0; - curr.toBeMarshaledMap.clear(); - curr.marshaledMap.clear(); - curr.typeIdIndex = 0; - curr.typeIdMap.clear(); - } - _writeEncapsCache = _writeEncapsCache.next; - } - else - { - curr = new WriteEncaps(); - } - curr.next = _writeEncapsStack; - _writeEncapsStack = curr; - } + WriteEncaps curr = new WriteEncaps(); + curr.next = _writeEncapsStack; + _writeEncapsStack = curr; _writeEncapsStack.start = _buf.position(); writeInt(0); // Placeholder for the encapsulation length. @@ -367,37 +304,15 @@ public class BasicStream int sz = _buf.position() - start; // Size includes size and version. _buf.putInt(start, sz); - { - WriteEncaps curr = _writeEncapsStack; - _writeEncapsStack = curr.next; - curr.next = _writeEncapsCache; - _writeEncapsCache = curr; - } + _writeEncapsStack = _writeEncapsStack.next; } public void startReadEncaps() { - { - ReadEncaps curr = _readEncapsCache; - if(curr != null) - { - if(curr.patchMap != null) - { - curr.patchMap.clear(); - curr.unmarshaledMap.clear(); - curr.typeIdIndex = 0; - curr.typeIdMap.clear(); - } - _readEncapsCache = _readEncapsCache.next; - } - else - { - curr = new ReadEncaps(); - } - curr.next = _readEncapsStack; - _readEncapsStack = curr; - } + ReadEncaps curr = new ReadEncaps(); + curr.next = _readEncapsStack; + _readEncapsStack = curr; _readEncapsStack.start = _buf.position(); @@ -450,12 +365,7 @@ public class BasicStream throw new Ice.UnmarshalOutOfBoundsException(); } - { - ReadEncaps curr = _readEncapsStack; - _readEncapsStack = curr.next; - curr.next = _readEncapsCache; - _readEncapsCache = curr; - } + _readEncapsStack = _readEncapsStack.next; } public void @@ -575,55 +485,13 @@ public class BasicStream return (int)(b < 0 ? b + 256 : b); } } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } } public void - writeTypeId(String id) - { - Integer index = (Integer)_writeEncapsStack.typeIdMap.get(id); - if(index != null) - { - writeBool(true); - writeSize(index.intValue()); - } - else - { - index = new Integer(++_writeEncapsStack.typeIdIndex); - _writeEncapsStack.typeIdMap.put(id, index); - writeBool(false); - writeString(id); - } - } - - public String - readTypeId() - { - String id; - Integer index; - final boolean isIndex = readBool(); - if(isIndex) - { - index = new Integer(readSize()); - id = (String)_readEncapsStack.typeIdMap.get(index); - if(id == null) - { - throw new Ice.UnmarshalOutOfBoundsException(); - } - } - else - { - id = readString(); - index = new Integer(++_readEncapsStack.typeIdIndex); - _readEncapsStack.typeIdMap.put(index, id); - } - return id; - } - - public void writeBlob(byte[] v) { expand(v.length); @@ -646,7 +514,7 @@ public class BasicStream _buf.get(v); return v; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -681,7 +549,7 @@ public class BasicStream { return _buf.get(); } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -698,7 +566,7 @@ public class BasicStream _buf.get(v); return v; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -736,7 +604,7 @@ public class BasicStream { return _buf.get() == 1; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -756,7 +624,7 @@ public class BasicStream } return v; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -780,9 +648,7 @@ public class BasicStream { writeSize(v.length); expand(v.length * 2); - java.nio.ShortBuffer shortBuf = _buf.asShortBuffer(); - shortBuf.put(v); - _buf.position(_buf.position() + v.length * 2); + _buf.putShortSeq(v); } } @@ -793,7 +659,7 @@ public class BasicStream { return _buf.getShort(); } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -807,12 +673,10 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 2); short[] v = new short[sz]; - java.nio.ShortBuffer shortBuf = _buf.asShortBuffer(); - shortBuf.get(v); - _buf.position(_buf.position() + sz * 2); + _buf.getShortSeq(v); return v; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -836,9 +700,7 @@ public class BasicStream { writeSize(v.length); expand(v.length * 4); - java.nio.IntBuffer intBuf = _buf.asIntBuffer(); - intBuf.put(v); - _buf.position(_buf.position() + v.length * 4); + _buf.putIntSeq(v); } } @@ -849,7 +711,7 @@ public class BasicStream { return _buf.getInt(); } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -863,12 +725,10 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 4); int[] v = new int[sz]; - java.nio.IntBuffer intBuf = _buf.asIntBuffer(); - intBuf.get(v); - _buf.position(_buf.position() + sz * 4); + _buf.getIntSeq(v); return v; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -892,9 +752,7 @@ public class BasicStream { writeSize(v.length); expand(v.length * 8); - java.nio.LongBuffer longBuf = _buf.asLongBuffer(); - longBuf.put(v); - _buf.position(_buf.position() + v.length * 8); + _buf.putLongSeq(v); } } @@ -905,7 +763,7 @@ public class BasicStream { return _buf.getLong(); } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -919,12 +777,10 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 8); long[] v = new long[sz]; - java.nio.LongBuffer longBuf = _buf.asLongBuffer(); - longBuf.get(v); - _buf.position(_buf.position() + sz * 8); + _buf.getLongSeq(v); return v; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -948,9 +804,7 @@ public class BasicStream { writeSize(v.length); expand(v.length * 4); - java.nio.FloatBuffer floatBuf = _buf.asFloatBuffer(); - floatBuf.put(v); - _buf.position(_buf.position() + v.length * 4); + _buf.putFloatSeq(v); } } @@ -961,7 +815,7 @@ public class BasicStream { return _buf.getFloat(); } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -975,12 +829,10 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 4); float[] v = new float[sz]; - java.nio.FloatBuffer floatBuf = _buf.asFloatBuffer(); - floatBuf.get(v); - _buf.position(_buf.position() + sz * 4); + _buf.getFloatSeq(v); return v; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -1004,9 +856,7 @@ public class BasicStream { writeSize(v.length); expand(v.length * 8); - java.nio.DoubleBuffer doubleBuf = _buf.asDoubleBuffer(); - doubleBuf.put(v); - _buf.position(_buf.position() + v.length * 8); + _buf.putDoubleSeq(v); } } @@ -1017,7 +867,7 @@ public class BasicStream { return _buf.getDouble(); } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -1031,12 +881,10 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 8); double[] v = new double[sz]; - java.nio.DoubleBuffer doubleBuf = _buf.asDoubleBuffer(); - doubleBuf.get(v); - _buf.position(_buf.position() + sz * 8); + _buf.getDoubleSeq(v); return v; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -1150,7 +998,7 @@ public class BasicStream assert(false); return ""; } - catch(java.nio.BufferUnderflowException ex) + catch(ByteBuffer.UnderflowException ex) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -1241,34 +1089,6 @@ public class BasicStream // } - public void - sliceObjects(boolean b) - { - _sliceObjects = b; - } - - void - writeInstance(Ice.Object v, Integer index) - { - writeInt(index.intValue()); - try - { - v.ice_preMarshal(); - } - catch(java.lang.Exception ex) - { - java.io.StringWriter sw = new java.io.StringWriter(); - java.io.PrintWriter pw = new java.io.PrintWriter(sw); - IceUtil.OutputBase out = new IceUtil.OutputBase(pw); - out.setUseTab(false); - out.print("exception raised by ice_preMarshal:\n"); - ex.printStackTrace(pw); - pw.flush(); - _instance.logger().warning(sw.toString()); - } - v.__write(this); - } - public int pos() { @@ -1367,7 +1187,7 @@ public class BasicStream _buf.limit(oldLimit); int pos = _buf.position(); _buf.position(0); - _buf = _bufferManager.reallocate(_buf, newCapacity); + reallocate(newCapacity); assert(_buf != null); _capacity = _buf.capacity(); _buf.limit(_capacity); @@ -1581,13 +1401,44 @@ public class BasicStream return buf.toString(); } + private void + allocate(int size) + { + ByteBuffer buf = null; + try + { + buf = ByteBuffer.allocate(size); + } + catch(OutOfMemoryError ex) + { + Ice.MarshalException e = new Ice.MarshalException(); + e.reason = "OutOfMemoryError occurred while allocating a ByteBuffer"; + e.initCause(ex); + throw e; + } + buf.order(ByteBuffer.LITTLE_ENDIAN); + _buf = buf; + } + + private void + reallocate(int size) + { + ByteBuffer old = _buf; + assert(old != null); + + allocate(size); + assert(_buf != null); + + old.position(0); + _buf.put(old); + } + private IceInternal.Instance _instance; - private BufferManager _bufferManager; - private java.nio.ByteBuffer _buf; - private int _capacity; // Cache capacity to avoid excessive method calls - private int _limit; // Cache limit to avoid excessive method calls - private byte[] _stringBytes; // Reusable array for reading strings - private char[] _stringChars; // Reusable array for reading strings + private ByteBuffer _buf; + private int _capacity; // Cache capacity to avoid excessive method calls. + private int _limit; // Cache limit to avoid excessive method calls. + private byte[] _stringBytes; // Reusable array for reading strings. + private char[] _stringChars; // Reusable array for reading strings. private static final class ReadEncaps { @@ -1597,10 +1448,6 @@ public class BasicStream byte encodingMajor; byte encodingMinor; - java.util.TreeMap patchMap; - java.util.TreeMap unmarshaledMap; - int typeIdIndex; - java.util.TreeMap typeIdMap; ReadEncaps next; } @@ -1608,24 +1455,15 @@ public class BasicStream { int start; - int writeIndex; - java.util.IdentityHashMap toBeMarshaledMap; - java.util.IdentityHashMap marshaledMap; - int typeIdIndex; - java.util.TreeMap typeIdMap; WriteEncaps next; } private ReadEncaps _readEncapsStack; private WriteEncaps _writeEncapsStack; - private ReadEncaps _readEncapsCache; - private WriteEncaps _writeEncapsCache; private int _readSlice; private int _writeSlice; - private boolean _sliceObjects; - private int _messageSizeMax; private static final class SeqData @@ -1642,8 +1480,6 @@ public class BasicStream } SeqData _seqDataStack; - private java.util.ArrayList _objectList; - private static java.util.HashMap _exceptionFactories = new java.util.HashMap(); private static java.lang.Object _factoryMutex = new java.lang.Object(); // Protects _exceptionFactories. } diff --git a/javae/src/IceInternal/BufferManager.java b/javae/src/IceInternal/BufferManager.java deleted file mode 100644 index 325e1d5cdc6..00000000000 --- a/javae/src/IceInternal/BufferManager.java +++ /dev/null @@ -1,129 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -package IceInternal; - -final class BufferManager -{ - BufferManager() - { - _head = null; - } - - java.nio.ByteBuffer - allocate(int size) - { - java.nio.ByteBuffer buf = getBuffer(size); - if(buf == null) - { - try - { - //buf = java.nio.ByteBuffer.allocateDirect(size); - buf = java.nio.ByteBuffer.allocate(size); - } - catch(OutOfMemoryError ex) - { - Ice.MemoryLimitException e = new Ice.MemoryLimitException(); - e.initCause(ex); - throw e; - } - buf.order(java.nio.ByteOrder.LITTLE_ENDIAN); - } - return buf; - } - - java.nio.ByteBuffer - reallocate(java.nio.ByteBuffer old, int size) - { - java.nio.ByteBuffer buf = getBuffer(size); - if(buf == null) - { - try - { - //buf = java.nio.ByteBuffer.allocateDirect(size); - buf = java.nio.ByteBuffer.allocate(size); - } - catch(OutOfMemoryError ex) - { - Ice.MemoryLimitException e = new Ice.MemoryLimitException(); - e.initCause(ex); - throw e; - } - buf.order(java.nio.ByteOrder.LITTLE_ENDIAN); - } - old.position(0); - buf.put(old); - reclaim(old); - return buf; - } - - synchronized void - reclaim(java.nio.ByteBuffer buf) - { - BufferNode node; - if(_nodeCache == null) - { - node = new BufferNode(); - } - else - { - node = _nodeCache; - _nodeCache = _nodeCache.next; - } - node.buf = buf; - node.capacity = buf.capacity(); - node.next = _head; - _head = node; - } - - private synchronized java.nio.ByteBuffer - getBuffer(int size) - { - BufferNode node = _head; - BufferNode prev = null; - while(node != null) - { - if(size <= node.capacity) - { - break; - } - prev = node; - node = node.next; - } - if(node != null) - { - if(prev != null) - { - prev.next = node.next; - } - else - { - _head = node.next; - } - node.next = _nodeCache; - _nodeCache = node; - node.buf.clear(); - return node.buf; - } - else - { - return null; - } - } - - private static final class BufferNode - { - java.nio.ByteBuffer buf; - int capacity; - BufferNode next; - } - - private BufferNode _head; - private BufferNode _nodeCache; -} diff --git a/javae/src/IceInternal/ByteBuffer.java b/javae/src/IceInternal/ByteBuffer.java new file mode 100755 index 00000000000..7a3cb3c85ff --- /dev/null +++ b/javae/src/IceInternal/ByteBuffer.java @@ -0,0 +1,756 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package IceInternal; + +public class ByteBuffer +{ + public + ByteBuffer() + { + _order = BIG_ENDIAN; + } + + public static final int BIG_ENDIAN = 0; + public static final int LITTLE_ENDIAN = 1; + + public int + order() + { + return _order; + } + + public ByteBuffer + order(int bo) + { + _order = bo; + return this; + } + + public static ByteBuffer + allocate(int capacity) + { + if(capacity < 0) + { + throw new IllegalArgumentException("capacity must be non-negative"); + } + ByteBuffer ret = new ByteBuffer(); + ret._position = 0; + ret._limit = capacity; + ret._capacity = capacity; + ret._bytes = new byte[capacity]; + return ret; + } + + public int + position() + { + return _position; + } + + public ByteBuffer + position(int pos) + { + if(pos < 0) + { + throw new IllegalArgumentException("position must be non-negative"); + } + if(pos > _limit) + { + throw new IllegalArgumentException("position must be less than limit"); + } + _position = pos; + return this; + } + + public int + limit() + { + return _limit; + } + + public ByteBuffer + limit(int newLimit) + { + if(newLimit < 0) + { + throw new IllegalArgumentException("limit must be non-negative"); + } + if(newLimit > _capacity) + { + throw new IllegalArgumentException("limit must be less than capacity"); + } + _limit = newLimit; + return this; + } + + public void + clear() + { + _position = 0; + _limit = _capacity; + } + + public int + remaining() + { + return _limit - _position; + } + + public boolean + hasRemaining() + { + return _position < _limit; + } + + public int + capacity() + { + return _capacity; + } + + public byte[] + array() + { + return _bytes; + } + + public ByteBuffer + put(ByteBuffer buf) + { + int len = buf.remaining(); + checkOverflow(len); + System.arraycopy(buf._bytes, buf._position, _bytes, _position, len); + _position += len; + return this; + } + + public byte + get() + { + checkUnderflow(1); + return _bytes[_position++]; + } + + public ByteBuffer + get(byte[] b) + { + return get(b, 0, b.length); + } + + public ByteBuffer + get(byte[] b, int offset, int length) + { + if(offset < 0) + { + throw new IllegalArgumentException("offset must be non-negative"); + } + if(offset + length > b.length) + { + throw new IllegalArgumentException("insufficient room beyond given offset in destination array"); + } + checkUnderflow(length); + System.arraycopy(_bytes, _position, b, offset, length); + _position += length; + return this; + } + + public ByteBuffer + put(byte b) + { + checkOverflow(1); + _bytes[_position++] = b; + return this; + } + + public ByteBuffer + put(byte[] b) + { + return put(b, 0, b.length); + } + + public ByteBuffer + put(byte[] b, int offset, int length) + { + if(offset < 0) + { + throw new IllegalArgumentException("offset must be non-negative"); + } + if(offset + length > b.length) + { + throw new IllegalArgumentException("insufficient data beyond given offset in source array"); + } + checkOverflow(length); + System.arraycopy(b, offset, _bytes, _position, length); + _position += length; + return this; + } + + public short + getShort() + { + checkUnderflow(2); + int high, low; + if(_order == BIG_ENDIAN) + { + high = _bytes[_position++] & 0xff; + low = _bytes[_position++] & 0xff; + } + else + { + low = _bytes[_position++] & 0xff; + high = _bytes[_position++] & 0xff; + } + return (short)(high << 8 | low); + } + + public void + getShortSeq(short[] seq) + { + checkUnderflow(seq.length * 2); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + int high = _bytes[_position++] & 0xff; + int low = _bytes[_position++] & 0xff; + seq[i] = (short)(high << 8 | low); + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + int low = _bytes[_position++] & 0xff; + int high = _bytes[_position++] & 0xff; + seq[i] = (short)(high << 8 | low); + } + } + } + + public ByteBuffer + putShort(short val) + { + checkOverflow(2); + if(_order == BIG_ENDIAN) + { + _bytes[_position++] = (byte)(val >>> 8); + _bytes[_position++] = (byte)val; + } + else + { + _bytes[_position++] = (byte)val; + _bytes[_position++] = (byte)(val >>> 8); + } + return this; + } + + public ByteBuffer + putShortSeq(short[] seq) + { + checkOverflow(seq.length * 2); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + _bytes[_position++] = (byte)(seq[i] >>> 8); + _bytes[_position++] = (byte)seq[i]; + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + _bytes[_position++] = (byte)seq[i]; + _bytes[_position++] = (byte)(seq[i] >>> 8); + } + } + return this; + } + + public int + getInt() + { + checkUnderflow(4); + int ret = 0; + if(_order == BIG_ENDIAN) + { + for(int shift = 24; shift >= 0; shift -= 8) + { + ret |= (int)(_bytes[_position++] & 0xff) << shift; + } + } + else + { + for(int shift = 0; shift < 32; shift += 8) + { + ret |= (int)(_bytes[_position++] & 0xff) << shift; + } + } + return ret; + } + + public void + getIntSeq(int[] seq) + { + checkUnderflow(seq.length * 4); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + int val = 0; + for(int shift = 24; shift >= 0; shift -= 8) + { + val |= (int)(_bytes[_position++] & 0xff) << shift; + } + seq[i] = val; + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + int val = 0; + for(int shift = 0; shift < 32; shift += 8) + { + val |= (int)(_bytes[_position++] & 0xff) << shift; + } + seq[i] = val; + } + } + } + + public ByteBuffer + putInt(int val) + { + putInt(_position, val); + _position += 4; + return this; + } + + public ByteBuffer + putInt(int pos, int val) + { + if(pos < 0) + { + throw new IllegalArgumentException("position must be non-negative"); + } + if(pos + 4 > _limit) + { + throw new IllegalArgumentException("position must be less than limit - 4"); + } + if(_order == BIG_ENDIAN) + { + for(int shift = 24; shift >= 0; shift -= 8) + { + _bytes[pos++] = (byte)((val >> shift) & 0xff); + } + } + else + { + for(int shift = 0; shift < 32; shift += 8) + { + _bytes[pos++] = (byte)((val >> shift) & 0xff); + } + } + return this; + } + + public ByteBuffer + putIntSeq(int[] seq) + { + checkOverflow(seq.length * 4); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + int val = seq[i]; + for(int shift = 24; shift >= 0; shift -= 8) + { + _bytes[_position++] = (byte)((val >> shift) & 0xff); + } + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + int val = seq[i]; + for(int shift = 0; shift < 32; shift += 8) + { + _bytes[_position++] = (byte)((val >> shift) & 0xff); + } + } + } + return this; + } + + public long + getLong() + { + checkUnderflow(8); + long ret = 0; + if(_order == BIG_ENDIAN) + { + for(int shift = 56; shift >= 0; shift -= 8) + { + ret |= (long)(_bytes[_position++] & 0xff) << shift; + } + } + else + { + for(int shift = 0; shift < 64; shift += 8) + { + ret |= (long)(_bytes[_position++] & 0xff) << shift; + } + } + return ret; + } + + public void + getLongSeq(long[] seq) + { + checkUnderflow(seq.length * 8); + for(int i = 0; i < seq.length; ++i) + { + if(_order == BIG_ENDIAN) + { + long val = 0; + for(int shift = 56; shift >= 0; shift -= 8) + { + val |= (long)(_bytes[_position++] & 0xff) << shift; + } + seq[i] = val; + } + else + { + long val = 0; + for(int shift = 0; shift < 64; shift += 8) + { + val |= (long)(_bytes[_position++] & 0xff) << shift; + } + seq[i] = val; + } + } + } + + public ByteBuffer + putLong(long val) + { + checkOverflow(8); + if(_order == BIG_ENDIAN) + { + for(int shift = 56; shift >= 0; shift -= 8) + { + _bytes[_position++] = (byte)((val >> shift) & 0xff); + } + } + else + { + for(int shift = 0; shift < 64; shift += 8) + { + _bytes[_position++] = (byte)((val >> shift) & 0xff); + } + } + return this; + } + + public ByteBuffer + putLongSeq(long[] seq) + { + checkOverflow(seq.length * 8); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + long val = seq[i]; + for(int shift = 56; shift >= 0; shift -= 8) + { + _bytes[_position++] = (byte)((val >> shift) & 0xff); + } + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + long val = seq[i]; + for(int shift = 0; shift < 64; shift += 8) + { + _bytes[_position++] = (byte)((val >> shift) & 0xff); + } + } + } + return this; + } + + public float + getFloat() + { + checkUnderflow(4); + int bits = 0; + if(_order == BIG_ENDIAN) + { + for(int shift = 24; shift >= 0; shift -= 8) + { + bits |= (int)(_bytes[_position++] & 0xff) << shift; + } + } + else + { + for(int shift = 0; shift < 32; shift += 8) + { + bits |= (int)(_bytes[_position++] & 0xff) << shift; + } + } + return Float.intBitsToFloat(bits); + } + + public void + getFloatSeq(float[] seq) + { + checkUnderflow(seq.length * 4); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + int bits = 0; + for(int shift = 24; shift >= 0; shift -= 8) + { + bits |= (int)(_bytes[_position++] & 0xff) << shift; + } + seq[i] = Float.intBitsToFloat(bits); + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + int bits = 0; + for(int shift = 0; shift < 32; shift += 8) + { + bits |= (int)(_bytes[_position++] & 0xff) << shift; + } + seq[i] = Float.intBitsToFloat(bits); + } + } + } + + public ByteBuffer + putFloat(float val) + { + checkOverflow(4); + int bits = Float.floatToIntBits(val); + if(_order == BIG_ENDIAN) + { + for(int shift = 24; shift >= 0; shift -= 8) + { + _bytes[_position++] = (byte)((bits >> shift) & 0xff); + } + } + else + { + for(int shift = 0; shift < 32; shift += 8) + { + _bytes[_position++] = (byte)((bits >> shift) & 0xff); + } + } + return this; + } + + public ByteBuffer + putFloatSeq(float[] seq) + { + checkOverflow(seq.length * 4); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + int bits = Float.floatToIntBits(seq[i]); + for(int shift = 24; shift >= 0; shift -= 8) + { + _bytes[_position++] = (byte)((bits >> shift) & 0xff); + } + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + int bits = Float.floatToIntBits(seq[i]); + for(int shift = 0; shift < 32; shift += 8) + { + _bytes[_position++] = (byte)((bits >> shift) & 0xff); + } + } + } + return this; + } + + public double + getDouble() + { + checkUnderflow(8); + long bits = 0; + if(_order == BIG_ENDIAN) + { + for(int shift = 56; shift >= 0; shift -= 8) + { + bits |= (long)(_bytes[_position++] & 0xff) << shift; + } + } + else + { + for(int shift = 0; shift < 64; shift += 8) + { + bits |= (long)(_bytes[_position++] & 0xff) << shift; + } + } + return Double.longBitsToDouble(bits); + } + + public void + getDoubleSeq(double[] seq) + { + checkUnderflow(seq.length * 8); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + long bits = 0; + for(int shift = 56; shift >= 0; shift -= 8) + { + bits |= (long)(_bytes[_position++] & 0xff) << shift; + } + seq[i] = Double.longBitsToDouble(bits); + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + long bits = 0; + for(int shift = 0; shift < 64; shift += 8) + { + bits |= (long)(_bytes[_position++] & 0xff) << shift; + } + seq[i] = Double.longBitsToDouble(bits); + } + } + } + + public ByteBuffer + putDouble(double val) + { + checkOverflow(8); + long bits = Double.doubleToLongBits(val); + if(_order == BIG_ENDIAN) + { + for(int shift = 56; shift >= 0; shift -= 8) + { + _bytes[_position++] = (byte)((bits >> shift) & 0xff); + } + } + else + { + for(int shift = 0; shift < 64; shift += 8) + { + _bytes[_position++] = (byte)((bits >> shift) & 0xff); + } + } + return this; + } + + public ByteBuffer + putDoubleSeq(double[] seq) + { + checkOverflow(seq.length * 8); + if(_order == BIG_ENDIAN) + { + for(int i = 0; i < seq.length; ++i) + { + long bits = Double.doubleToLongBits(seq[i]); + for(int shift = 56; shift >= 0; shift -= 8) + { + _bytes[_position++] = (byte)((bits >> shift) & 0xff); + } + } + } + else + { + for(int i = 0; i < seq.length; ++i) + { + long bits = Double.doubleToLongBits(seq[i]); + for(int shift = 0; shift < 64; shift += 8) + { + _bytes[_position++] = (byte)((bits >> shift) & 0xff); + } + } + } + return this; + } + + byte[] + rawBytes() + { + return _bytes; + } + + byte[] + rawBytes(int offset, int len) + { + if(offset + len > _limit) + { + throw new UnderflowException(); + } + byte[] rc = new byte[len]; + System.arraycopy(_bytes, offset, rc, 0, len); + return rc; + } + + private void + checkUnderflow(int size) + { + if(_position + size > _limit) + { + throw new UnderflowException(); + } + } + + private void + checkOverflow(int size) + { + if(_position + size > _limit) + { + throw new OverflowException(); + } + } + + public static class UnderflowException extends RuntimeException + { + public UnderflowException() + { + super("buffer underflow"); + } + } + + public static class OverflowException extends RuntimeException + { + public OverflowException() + { + super("buffer overflow"); + } + } + + private int _position; + private int _limit; + private int _capacity; + private byte[] _bytes; + private int _order; +} diff --git a/javae/src/IceInternal/Incoming.java b/javae/src/IceInternal/Incoming.java index 75c909d5f5d..077e1dc0f51 100644 --- a/javae/src/IceInternal/Incoming.java +++ b/javae/src/IceInternal/Incoming.java @@ -20,25 +20,7 @@ final public class Incoming extends IncomingBase } // - // Do NOT use a finalizer, this would cause a severe performance - // penalty! We must make sure that __destroy() is called instead, - // to reclaim resources. - // - public void - __destroy() - { - if(_is != null) - { - _is.destroy(); - _is = null; - } - - super.__destroy(); - } - - // - // This function allows this object to be reused, rather than - // reallocated. + // This function allows this object to be reused, rather than reallocated. // public void reset(Instance instance, Ice.ConnectionI connection, Ice.ObjectAdapter adapter, boolean response) diff --git a/javae/src/IceInternal/IncomingBase.java b/javae/src/IceInternal/IncomingBase.java index d1a1e7dcd99..eba65007db1 100644 --- a/javae/src/IceInternal/IncomingBase.java +++ b/javae/src/IceInternal/IncomingBase.java @@ -24,7 +24,6 @@ public class IncomingBase _current.con = _connection; _cookie = new Ice.LocalObjectHolder(); - } protected @@ -50,21 +49,6 @@ public class IncomingBase } // - // Do NOT use a finalizer, this would cause a severe performance - // penalty! We must make sure that __destroy() is called instead, - // to reclaim resources. - // - public synchronized void - __destroy() - { - if(_os != null) - { - _os.destroy(); - _os = null; - } - } - - // // This function allows this object to be reused, rather than reallocated. // public void diff --git a/javae/src/IceInternal/InetSocketAddress.java b/javae/src/IceInternal/InetSocketAddress.java new file mode 100644 index 00000000000..dc87a53db3b --- /dev/null +++ b/javae/src/IceInternal/InetSocketAddress.java @@ -0,0 +1,81 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package IceInternal; + +class InetSocketAddress +{ + InetSocketAddress(String host, int port) + { + try + { + _addr = java.net.InetAddress.getByName(host); + } + catch(java.net.UnknownHostException ex) + { + Ice.DNSException e = new Ice.DNSException(); + e.host = host; + e.initCause(ex); + throw e; + } + catch(RuntimeException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + _port = port; + } + + InetSocketAddress(java.net.InetAddress addr, int port) + { + _addr = addr; + _port = port; + } + + java.net.InetAddress + getAddress() + { + return _addr; + } + + String + getHostName() + { + return _addr.getHostName(); + } + + int + getPort() + { + return _port; + } + + public int + hashCode() + { + return 5 * _addr.hashCode() + _port; + } + + public String + toString() + { + return _addr.toString() + ":" + _port; + } + + public boolean + equals(Object rhs) + { + InetSocketAddress addr = (InetSocketAddress)rhs; + return _addr.equals(addr._addr) && _port == addr._port; + } + + private java.net.InetAddress _addr; + private int _port; +} diff --git a/javae/src/IceInternal/Instance.java b/javae/src/IceInternal/Instance.java index 3e50a8ed7bc..d575a99c77d 100644 --- a/javae/src/IceInternal/Instance.java +++ b/javae/src/IceInternal/Instance.java @@ -184,13 +184,6 @@ public class Instance adapterFactory.flushBatchRequests(); } - public BufferManager - bufferManager() - { - // No mutex lock, immutable. - return _bufferManager; - } - // // Only for use by Ice.CommunicatorI // @@ -303,8 +296,6 @@ public class Instance _outgoingConnectionFactory = new OutgoingConnectionFactory(this); _objectAdapterFactory = new ObjectAdapterFactory(this, communicator); - - _bufferManager = new BufferManager(); } catch(Ice.LocalException ex) { @@ -317,14 +308,14 @@ public class Instance finalize() throws Throwable { - assert(_destroyed); - assert(_referenceFactory == null); - assert(_proxyFactory == null); - assert(_outgoingConnectionFactory == null); - assert(_objectAdapterFactory == null); - assert(_routerManager == null); - assert(_locatorManager == null); - assert(_endpointFactoryManager == null); + IceUtil.Assert.FinalizerAssert(_destroyed); + IceUtil.Assert.FinalizerAssert(_referenceFactory == null); + IceUtil.Assert.FinalizerAssert(_proxyFactory == null); + IceUtil.Assert.FinalizerAssert(_outgoingConnectionFactory == null); + IceUtil.Assert.FinalizerAssert(_objectAdapterFactory == null); + IceUtil.Assert.FinalizerAssert(_routerManager == null); + IceUtil.Assert.FinalizerAssert(_locatorManager == null); + IceUtil.Assert.FinalizerAssert(_endpointFactoryManager == null); super.finalize(); } @@ -458,7 +449,6 @@ public class Instance private EndpointFactoryManager _endpointFactoryManager; private java.util.Map _defaultContext; private static java.util.Map _emptyContext = new java.util.HashMap(); - private final BufferManager _bufferManager; // Immutable, not reset by destroy(). private static boolean _oneOffDone = false; } diff --git a/javae/src/IceInternal/Network.java b/javae/src/IceInternal/Network.java index d7847c6dfc3..d4d98dfea8d 100644 --- a/javae/src/IceInternal/Network.java +++ b/javae/src/IceInternal/Network.java @@ -88,38 +88,14 @@ public final class Network return false; } - public static java.nio.channels.SocketChannel + public static java.net.Socket createTcpSocket() { try { - java.nio.channels.SocketChannel fd = java.nio.channels.SocketChannel.open(); - java.net.Socket socket = fd.socket(); - socket.setTcpNoDelay(true); - socket.setKeepAlive(true); - return fd; - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - - public static java.nio.channels.ServerSocketChannel - createTcpServerSocket() - { - try - { - java.nio.channels.ServerSocketChannel fd = java.nio.channels.ServerSocketChannel.open(); - // - // It's not possible to set TCP_NODELAY or KEEP_ALIVE - // on a server socket in Java - // - //java.net.Socket socket = fd.socket(); - //socket.setTcpNoDelay(true); - //socket.setKeepAlive(true); + java.net.Socket fd = new java.net.Socket(); + fd.setTcpNoDelay(true); + fd.setKeepAlive(true); return fd; } catch(java.io.IOException ex) @@ -131,7 +107,7 @@ public final class Network } public static void - closeSocket(java.nio.channels.SelectableChannel fd) + closeSocket(java.net.Socket fd) { try { @@ -145,249 +121,13 @@ public final class Network } } - public static void - setBlock(java.nio.channels.SelectableChannel fd, boolean block) - { - try - { - fd.configureBlocking(block); - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - - public static java.net.InetSocketAddress - doBind(java.nio.channels.ServerSocketChannel fd, java.net.InetSocketAddress addr) - { - try - { - java.net.ServerSocket sock = fd.socket(); - sock.bind(addr); - return (java.net.InetSocketAddress)sock.getLocalSocketAddress(); - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - - public static void - doConnect(java.nio.channels.SocketChannel fd, java.net.InetSocketAddress addr, int timeout) - { - try - { - if(!fd.connect(addr)) - { - int delay; - if(timeout > 0 && timeout < 100) - { - delay = timeout; - } - else - { - delay = 100; // 100 ms - } - - int timer = 0; - while(!fd.finishConnect()) - { - if(timeout > 0 && timer >= timeout) - { - fd.close(); - throw new Ice.ConnectTimeoutException(); - } - try - { - Thread.sleep(delay); - timer += delay; - } - catch(InterruptedException ex) - { - } - } - } - } - catch(java.net.ConnectException ex) - { - try - { - fd.close(); - } - catch(java.io.IOException e) - { - // ignore - } - - Ice.ConnectFailedException se; - if(connectionRefused(ex)) - { - se = new Ice.ConnectionRefusedException(); - } - else - { - se = new Ice.ConnectFailedException(); - } - se.initCause(ex); - throw se; - } - catch(java.io.IOException ex) - { - try - { - fd.close(); - } - catch(java.io.IOException e) - { - // ignore - } - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - - public static java.nio.channels.SocketChannel - doAccept(java.nio.channels.ServerSocketChannel fd, int timeout) - { - java.nio.channels.SocketChannel result = null; - while(result == null) - { - try - { - result = fd.accept(); - if(result == null) - { - java.nio.channels.Selector selector = java.nio.channels.Selector.open(); - - try - { - while(true) - { - try - { - java.nio.channels.SelectionKey key = - fd.register(selector, java.nio.channels.SelectionKey.OP_ACCEPT); - int n; - if(timeout > 0) - { - n = selector.select(timeout); - } - else if(timeout == 0) - { - n = selector.selectNow(); - } - else - { - n = selector.select(); - } - - if(n == 0) - { - throw new Ice.TimeoutException(); - } - - break; - } - catch(java.io.IOException ex) - { - if(interrupted(ex)) - { - continue; - } - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - } - finally - { - try - { - selector.close(); - } - catch(java.io.IOException ex) - { - // Ignore - } - } - } - } - catch(java.io.IOException ex) - { - if(interrupted(ex)) - { - continue; - } - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - - try - { - java.net.Socket socket = result.socket(); - socket.setTcpNoDelay(true); - socket.setKeepAlive(true); - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - - return result; - } - - public static void - setRecvBufferSize(java.nio.channels.ServerSocketChannel fd, int size) - { - try - { - java.net.ServerSocket socket = fd.socket(); - socket.setReceiveBufferSize(size); - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - - public static int - getRecvBufferSize(java.nio.channels.ServerSocketChannel fd) - { - int size; - try - { - java.net.ServerSocket socket = fd.socket(); - size = socket.getReceiveBufferSize(); - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - return size; - } - - public static java.net.InetSocketAddress + public static InetSocketAddress getAddress(String host, int port) { try { java.net.InetAddress addr = java.net.InetAddress.getByName(host); - return new java.net.InetSocketAddress(addr, port); + return new InetSocketAddress(addr, port); } catch(java.net.UnknownHostException ex) { @@ -427,140 +167,22 @@ public final class Network // } - if(addr == null) - { - // - // Iterate over the network interfaces and pick an IP - // address (preferably not the loopback address). - // - java.net.InetAddress loopback = null; - try - { - java.util.Enumeration ni = java.net.NetworkInterface.getNetworkInterfaces(); - while(addr == null && ni.hasMoreElements()) - { - java.net.NetworkInterface i = (java.net.NetworkInterface)ni.nextElement(); - java.util.Enumeration addrs = i.getInetAddresses(); - while(addr == null && addrs.hasMoreElements()) - { - java.net.InetAddress a = (java.net.InetAddress)addrs.nextElement(); - if(!a.isLoopbackAddress()) - { - addr = a; - } - else - { - loopback = a; - } - } - } - } - catch(java.net.SocketException e) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(e); - throw se; - } - - if(addr == null) - { - addr = loopback; // Use the loopback address as the last resort. - } - } - - assert(addr != null); - return addr; - } - - public static final class SocketPair - { - public java.nio.channels.spi.AbstractSelectableChannel source; - public java.nio.channels.WritableByteChannel sink; - } - - public static SocketPair - createPipe() - { - SocketPair fds = new SocketPair(); - - // - // TODO: This method should really be very simple. Unfortunately, - // there's a bug in the Win32 JDK (#4494292) which prevents the - // Selector from properly detecting input on a Pipe's source - // channel, so we resort to creating a socket pair. This bug has - // supposedly been fixed for JDK 1.4.1. - // - //java.nio.channels.Pipe pipe = java.nio.channels.Pipe.open(); - //fds.sink = pipe.sink(); - //fds.source = pipe.source(); - // - - java.nio.channels.ServerSocketChannel fd = createTcpServerSocket(); - - java.net.InetSocketAddress addr = new java.net.InetSocketAddress("127.0.0.1", 0); - - addr = doBind(fd, addr); - - try - { - java.nio.channels.SocketChannel sink = createTcpSocket(); - fds.sink = sink; - try - { - doConnect(sink, addr, -1); - fds.source = doAccept(fd, -1); - } - catch(Ice.LocalException ex) - { - try - { - fds.sink.close(); - } - catch(java.io.IOException e) - { - } - throw ex; - } - } - finally - { - try - { - fd.close(); - } - catch(java.io.IOException ex) - { - } - } - - return fds; - } - - public static String - fdToString(java.nio.channels.SelectableChannel fd) - { - if(fd == null) - { - return "<closed>"; - } - - java.net.InetAddress localAddr = null, remoteAddr = null; - int localPort = -1, remotePort = -1; - - if(fd instanceof java.nio.channels.SocketChannel) - { - java.net.Socket socket = ((java.nio.channels.SocketChannel)fd).socket(); - localAddr = socket.getLocalAddress(); - localPort = socket.getLocalPort(); - remoteAddr = socket.getInetAddress(); - remotePort = socket.getPort(); - } - else + if(addr == null) { - assert(false); + try + { + addr = java.net.InetAddress.getByName("127.0.0.1"); + } + catch(java.net.UnknownHostException ex) + { + Ice.DNSException e = new Ice.DNSException(); + e.host = "127.0.0.1"; + throw e; + } } - return addressesToString(localAddr, localPort, remoteAddr, remotePort); + assert(addr != null); + return addr; } public static String @@ -603,7 +225,7 @@ public final class Network } public static String - addrToString(java.net.InetSocketAddress addr) + addrToString(InetSocketAddress addr) { StringBuffer s = new StringBuffer(); s.append(addr.getAddress().getHostAddress()); diff --git a/javae/src/IceInternal/ObjectAdapterFactory.java b/javae/src/IceInternal/ObjectAdapterFactory.java index 7caa17ef2b7..c1eee8fc4fa 100644 --- a/javae/src/IceInternal/ObjectAdapterFactory.java +++ b/javae/src/IceInternal/ObjectAdapterFactory.java @@ -75,17 +75,20 @@ public final class ObjectAdapterFactory // // Now we wait for deactivation of each object adapter. // - java.util.Iterator i = _adapters.values().iterator(); - while(i.hasNext()) - { - Ice.ObjectAdapter adapter = (Ice.ObjectAdapter)i.next(); - adapter.waitForDeactivate(); - } - + if(_adapters != null) + { + java.util.Iterator i = _adapters.values().iterator(); + while(i.hasNext()) + { + Ice.ObjectAdapter adapter = (Ice.ObjectAdapter)i.next(); + adapter.waitForDeactivate(); + } + } + // // We're done, now we can throw away the object adapters. // - _adapters.clear(); + _adapters = null; synchronized(this) { @@ -177,10 +180,10 @@ public final class ObjectAdapterFactory finalize() throws Throwable { - assert(_instance == null); - assert(_communicator == null); - assert(_adapters.size() == 0); - assert(!_waitForShutdown); + IceUtil.Assert.FinalizerAssert(_instance == null); + IceUtil.Assert.FinalizerAssert(_communicator == null); + IceUtil.Assert.FinalizerAssert(_adapters == null); + IceUtil.Assert.FinalizerAssert(!_waitForShutdown); super.finalize(); } diff --git a/javae/src/IceInternal/Outgoing.java b/javae/src/IceInternal/Outgoing.java index 90a03c815e2..4293ef60520 100644 --- a/javae/src/IceInternal/Outgoing.java +++ b/javae/src/IceInternal/Outgoing.java @@ -25,25 +25,7 @@ public final class Outgoing } // - // Do NOT use a finalizer, this would cause a severe performance - // penalty! We must make sure that destroy() is called instead, to - // reclaim resources. - // - public void - destroy() - { - assert(_is != null); - _is.destroy(); - _is = null; - - assert(_os != null); - _os.destroy(); - _os = null; - } - - // - // This function allows this object to be reused, rather than - // reallocated. + // This function allows this object to be reused, rather than reallocated. // public void reset(String operation, Ice.OperationMode mode, java.util.Map context) diff --git a/javae/src/IceInternal/OutgoingConnectionFactory.java b/javae/src/IceInternal/OutgoingConnectionFactory.java index 40dfbf07c56..ba909b75ba9 100644 --- a/javae/src/IceInternal/OutgoingConnectionFactory.java +++ b/javae/src/IceInternal/OutgoingConnectionFactory.java @@ -65,7 +65,7 @@ public final class OutgoingConnectionFactory // outside the thread synchronization. // connections = _connections; - _connections = new java.util.HashMap(); + _connections = null; } // @@ -493,8 +493,8 @@ public final class OutgoingConnectionFactory finalize() throws Throwable { - assert(_destroyed); - assert(_connections.isEmpty()); + IceUtil.Assert.FinalizerAssert(_destroyed); + IceUtil.Assert.FinalizerAssert(_connections == null); super.finalize(); } diff --git a/javae/src/IceInternal/ServantManager.java b/javae/src/IceInternal/ServantManager.java index 9135e545a80..701eb743f44 100644 --- a/javae/src/IceInternal/ServantManager.java +++ b/javae/src/IceInternal/ServantManager.java @@ -165,7 +165,7 @@ public final class ServantManager // not been called if the associated object adapter was not // properly deactivated. // - //assert(_instance == null); + //IceUtil.Assert.FinalizerAssert(_instance == null); super.finalize(); } diff --git a/javae/src/IceInternal/TcpAcceptor.java b/javae/src/IceInternal/TcpAcceptor.java index 55dafb1d993..348b900078e 100644 --- a/javae/src/IceInternal/TcpAcceptor.java +++ b/javae/src/IceInternal/TcpAcceptor.java @@ -11,12 +11,6 @@ package IceInternal; class TcpAcceptor implements Acceptor { - public java.nio.channels.ServerSocketChannel - fd() - { - return _fd; - } - public void close() { @@ -26,7 +20,7 @@ class TcpAcceptor implements Acceptor _logger.trace(_traceLevels.networkCat, s); } - java.nio.channels.ServerSocketChannel fd; + java.net.ServerSocket fd; synchronized(this) { fd = _fd; @@ -60,24 +54,56 @@ class TcpAcceptor implements Acceptor public Transceiver accept(int timeout) { - java.nio.channels.SocketChannel fd = Network.doAccept(_fd, timeout); + java.net.Socket fd = null; + try + { + if(timeout == -1) + { + timeout = 0; // Infinite + } + else if(timeout == 0) + { + timeout = 1; + } + _fd.setSoTimeout(timeout); + fd = _fd.accept(); + } + catch(java.io.InterruptedIOException ex) + { + Ice.TimeoutException e = new Ice.TimeoutException(); + e.initCause(ex); + throw e; + } + catch(java.io.IOException ex) + { + Ice.SocketException e = new Ice.SocketException(); + e.initCause(ex); + throw e; + } - if(_traceLevels.network >= 1) - { - String s = "accepted tcp connection\n" + Network.fdToString(fd); - _logger.trace(_traceLevels.networkCat, s); - } + if(_traceLevels.network >= 1) + { + String s = "accepted tcp connection\n" + Network.fdToString(fd); + _logger.trace(_traceLevels.networkCat, s); + } - return new TcpTransceiver(_instance, fd); + return new TcpTransceiver(_instance, fd); } public void connectToSelf() { - java.nio.channels.SocketChannel fd = Network.createTcpSocket(); - Network.setBlock(fd, false); - Network.doConnect(fd, _addr, -1); - Network.closeSocket(fd); + try + { + java.net.Socket fd = new java.net.Socket(_addr.getAddress(), _addr.getPort()); + fd.close(); + } + catch(java.io.IOException ex) + { + Ice.SocketException e = new Ice.SocketException(); + e.initCause(ex); + throw e; + } } public String @@ -89,7 +115,7 @@ class TcpAcceptor implements Acceptor final boolean equivalent(String host, int port) { - java.net.InetSocketAddress addr = Network.getAddress(host, port); + InetSocketAddress addr = Network.getAddress(host, port); return addr.equals(_addr); } @@ -113,19 +139,45 @@ class TcpAcceptor implements Acceptor try { - _fd = Network.createTcpServerSocket(); - Network.setBlock(_fd, false); - _addr = new java.net.InetSocketAddress(host, port); + _addr = Network.getAddress(host, port); if(_traceLevels.network >= 2) { String s = "attempting to bind to tcp socket " + toString(); _logger.trace(_traceLevels.networkCat, s); } - _addr = Network.doBind(_fd, _addr); + _fd = new java.net.ServerSocket(port, _backlog, _addr.getAddress()); + _addr = new InetSocketAddress(_addr.getAddress(), _fd.getLocalPort()); + } + catch(java.io.IOException ex) + { + if(_fd != null) + { + try + { + _fd.close(); + } + catch(java.io.IOException e) + { + } + _fd = null; + } + Ice.SocketException e = new Ice.SocketException(); + e.initCause(ex); + throw e; } catch(RuntimeException ex) { - _fd = null; + if(_fd != null) + { + try + { + _fd.close(); + } + catch(java.io.IOException e) + { + } + _fd = null; + } throw ex; } } @@ -134,7 +186,7 @@ class TcpAcceptor implements Acceptor finalize() throws Throwable { - assert(_fd == null); + IceUtil.Assert.FinalizerAssert(_fd == null); super.finalize(); } @@ -142,7 +194,7 @@ class TcpAcceptor implements Acceptor private Instance _instance; private TraceLevels _traceLevels; private Ice.Logger _logger; - private java.nio.channels.ServerSocketChannel _fd; + private java.net.ServerSocket _fd; private int _backlog; - private java.net.InetSocketAddress _addr; + private InetSocketAddress _addr; } diff --git a/javae/src/IceInternal/TcpConnector.java b/javae/src/IceInternal/TcpConnector.java index edc79f2bb3c..a3bdfe13112 100644 --- a/javae/src/IceInternal/TcpConnector.java +++ b/javae/src/IceInternal/TcpConnector.java @@ -11,26 +11,165 @@ package IceInternal; final class TcpConnector implements Connector { + private static class ConnectThread extends Thread + { + ConnectThread(InetSocketAddress addr) + { + _addr = addr; + } + + public void + run() + { + try + { + java.net.Socket fd = new java.net.Socket(_addr.getAddress(), _addr.getPort()); + synchronized(this) + { + _fd = fd; + notifyAll(); + } + } + catch(java.io.IOException ex) + { + synchronized(this) + { + _ex = ex; + notifyAll(); + } + } + } + + java.net.Socket + getFd(int timeout) + throws java.io.IOException + { + java.net.Socket fd = null; + + synchronized(this) + { + while(_fd == null && _ex == null) + { + try + { + wait(timeout); + break; + } + catch(InterruptedException ex) + { + continue; + } + } + + if(_ex != null) + { + throw _ex; + } + + fd = _fd; + _fd = null; + } + + return fd; + } + + private InetSocketAddress _addr; + private java.net.Socket _fd; + private java.io.IOException _ex; + } + public Transceiver connect(int timeout) { - if(_traceLevels.network >= 2) - { - String s = "trying to establish tcp connection to " + toString(); - _logger.trace(_traceLevels.networkCat, s); - } - - java.nio.channels.SocketChannel fd = Network.createTcpSocket(); - Network.setBlock(fd, false); - Network.doConnect(fd, _addr, timeout); + if(_traceLevels.network >= 2) + { + String s = "trying to establish tcp connection to " + toString(); + _logger.trace(_traceLevels.networkCat, s); + } - if(_traceLevels.network >= 1) + java.net.Socket fd = null; + try + { + // + // If a connect timeout is specified, do the connect in a separate thread. + // + if(timeout >= 0) + { + ConnectThread ct = new ConnectThread(_addr); + ct.start(); + fd = ct.getFd(timeout == 0 ? 1 : timeout); + if(fd == null) + { + throw new Ice.ConnectTimeoutException(); + } + } + else + { + fd = new java.net.Socket(_addr.getAddress(), _addr.getPort()); + } + } + catch(java.net.ConnectException ex) { - String s = "tcp connection established\n" + Network.fdToString(fd); - _logger.trace(_traceLevels.networkCat, s); + if(fd != null) + { + try + { + fd.close(); + } + catch(java.io.IOException e) + { + } + } + Ice.ConnectFailedException se; + if(Network.connectionRefused(ex)) + { + se = new Ice.ConnectionRefusedException(); + } + else + { + se = new Ice.ConnectFailedException(); + } + se.initCause(ex); + throw se; } + catch(java.io.IOException ex) + { + if(fd != null) + { + try + { + fd.close(); + } + catch(java.io.IOException e) + { + } + } + Ice.SocketException e = new Ice.SocketException(); + e.initCause(ex); + throw e; + } + catch(RuntimeException ex) + { + if(fd != null) + { + try + { + fd.close(); + } + catch(java.io.IOException e) + { + } + } + throw ex; + } + + if(_traceLevels.network >= 1) + { + String s = "tcp connection established\n" + IceInternal.Network.fdToString(fd); + _logger.trace(_traceLevels.networkCat, s); + } - return new TcpTransceiver(_instance, fd); + return new TcpTransceiver(_instance, fd); } public String @@ -54,5 +193,5 @@ final class TcpConnector implements Connector private Instance _instance; private TraceLevels _traceLevels; private Ice.Logger _logger; - private java.net.InetSocketAddress _addr; + private InetSocketAddress _addr; } diff --git a/javae/src/IceInternal/TcpEndpoint.java b/javae/src/IceInternal/TcpEndpoint.java index bd6e0b94366..ca3e49df89d 100644 --- a/javae/src/IceInternal/TcpEndpoint.java +++ b/javae/src/IceInternal/TcpEndpoint.java @@ -359,7 +359,7 @@ final class TcpEndpoint implements Endpoint // // We do the most time-consuming part of the comparison last. // - java.net.InetSocketAddress laddr = null; + InetSocketAddress laddr = null; try { laddr = Network.getAddress(_host, _port); @@ -368,7 +368,7 @@ final class TcpEndpoint implements Endpoint { } - java.net.InetSocketAddress raddr = null; + InetSocketAddress raddr = null; try { raddr = Network.getAddress(p._host, p._port); diff --git a/javae/src/IceInternal/TcpTransceiver.java b/javae/src/IceInternal/TcpTransceiver.java index 691b0da58a0..9a8a1b66cbc 100644 --- a/javae/src/IceInternal/TcpTransceiver.java +++ b/javae/src/IceInternal/TcpTransceiver.java @@ -11,13 +11,6 @@ package IceInternal; final class TcpTransceiver implements Transceiver { - public java.nio.channels.SelectableChannel - fd() - { - assert(_fd != null); - return _fd; - } - public void close() { @@ -29,17 +22,17 @@ final class TcpTransceiver implements Transceiver synchronized(this) { - assert(_fd != null); - try - { - _fd.close(); - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } + assert(_fd != null); + try + { + _fd.close(); + } + catch(java.io.IOException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } finally { _fd = null; @@ -50,160 +43,78 @@ final class TcpTransceiver implements Transceiver public void shutdownWrite() { - if(_traceLevels.network >= 2) - { - String s = "shutting down tcp connection for writing\n" + toString(); - _logger.trace(_traceLevels.networkCat, s); - } - - assert(_fd != null); - java.net.Socket socket = _fd.socket(); - try - { - socket.shutdownOutput(); // Shutdown socket for writing - } - catch(java.net.SocketException ex) - { - // - // Ignore errors indicating that we are shutdown already. - // - if(Network.notConnected(ex)) - { - return; - } - - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } + // + // Not implemented. + // } public void shutdownReadWrite() { - if(_traceLevels.network >= 2) - { - String s = "shutting down tcp connection for reading and writing\n" + toString(); - _logger.trace(_traceLevels.networkCat, s); - } + if(_traceLevels.network >= 2) + { + String s = "shutting down tcp connection for reading and writing\n" + toString(); + _logger.trace(_traceLevels.networkCat, s); + } - assert(_fd != null); - java.net.Socket socket = _fd.socket(); - try - { - // - // TODO: Java does not support SHUT_RDWR. Calling both - // shutdownInput and shutdownOutput results in an exception. - // - socket.shutdownInput(); // Shutdown socket for reading - //socket.shutdownOutput(); // Shutdown socket for writing - } - catch(java.net.SocketException ex) - { - // Ignore. - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } + assert(_fd != null); + + _shutdown = true; } public void write(BasicStream stream, int timeout) { - java.nio.ByteBuffer buf = stream.prepareWrite(); + ByteBuffer buf = stream.prepareWrite(); - java.nio.channels.Selector selector = null; + byte[] data = buf.array(); try { - while(buf.hasRemaining()) + if(timeout == -1) { - try - { - assert(_fd != null); - int ret = _fd.write(buf); - - if(ret == -1) - { - throw new Ice.ConnectionLostException(); - } - - if(ret == 0) - { - if(timeout == 0) - { - throw new Ice.TimeoutException(); - } - - if(selector == null) - { - selector = java.nio.channels.Selector.open(); - _fd.register(selector, java.nio.channels.SelectionKey.OP_WRITE, null); - } - - try - { - if(timeout > 0) - { - long start = System.currentTimeMillis(); - int n = selector.select(timeout); - if(n == 0 && System.currentTimeMillis() >= start + timeout) - { - throw new Ice.TimeoutException(); - } - } - else - { - selector.select(); - } - } - catch(java.io.InterruptedIOException ex) - { - // Ignore. - } - - continue; - } - - if(_traceLevels.network >= 3) - { - String s = "sent " + ret + " of " + buf.limit() + " bytes via tcp\n" + toString(); - _logger.trace(_traceLevels.networkCat, s); - } - } - catch(java.io.InterruptedIOException ex) - { - continue; - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } + timeout = 0; // Infinite + } + else if(timeout == 0) + { + timeout = 1; } + _fd.setSoTimeout(timeout); + } + catch(java.net.SocketException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; } - finally + + while(buf.hasRemaining()) { - if(selector != null) + int pos = buf.position(); + try { - try - { - selector.close(); - } - catch(java.io.IOException ex) + assert(_fd != null); + int rem = buf.remaining(); + _out.write(data, pos, rem); + buf.position(pos + rem); + + if(_traceLevels.network >= 3) { - // Ignore. + String s = "sent " + rem + " of " + buf.limit() + " bytes via tcp\n" + toString(); + _logger.trace(_traceLevels.networkCat, s); } + + break; + } + catch(java.io.InterruptedIOException ex) + { + buf.position(pos + ex.bytesTransferred); + } + catch(java.io.IOException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; } } } @@ -211,109 +122,81 @@ final class TcpTransceiver implements Transceiver public void read(BasicStream stream, int timeout) { - java.nio.ByteBuffer buf = stream.prepareRead(); + ByteBuffer buf = stream.prepareRead(); - int remaining = 0; - if(_traceLevels.network >= 3) - { - remaining = buf.remaining(); - } + int remaining = 0; + if(_traceLevels.network >= 3) + { + remaining = buf.remaining(); + } - java.nio.channels.Selector selector = null; + byte[] data = buf.array(); - try + int interval = 500; + if(timeout >= 0 && timeout < interval) { - while(buf.hasRemaining()) + interval = timeout; + } + + while(buf.hasRemaining() && !_shutdown) + { + int pos = buf.position(); + try { - try + _fd.setSoTimeout(interval); + assert(_fd != null); + int ret = _in.read(data, pos, buf.remaining()); + + if(ret == -1) { - assert(_fd != null); - int ret = _fd.read(buf); - - if(ret == -1) + throw new Ice.ConnectionLostException(); + } + + if(ret > 0) + { + if(_traceLevels.network >= 3) { - throw new Ice.ConnectionLostException(); + String s = "received " + ret + " of " + remaining + " bytes via tcp\n" + toString(); + _logger.trace(_traceLevels.networkCat, s); } - - if(ret == 0) - { - if(timeout == 0) - { - throw new Ice.TimeoutException(); - } - if(selector == null) - { - selector = java.nio.channels.Selector.open(); - _fd.register(selector, java.nio.channels.SelectionKey.OP_READ, null); - } - - try - { - if(timeout > 0) - { - long start = System.currentTimeMillis(); - int n = selector.select(timeout); - if(n == 0 && System.currentTimeMillis() >= start + timeout) - { - throw new Ice.TimeoutException(); - } - } - else - { - selector.select(); - } - } - catch(java.io.InterruptedIOException ex) - { - // Ignore. - } - - continue; - } - - if(ret > 0) - { - if(_traceLevels.network >= 3) - { - String s = "received " + ret + " of " + remaining + " bytes via tcp\n" + toString(); - _logger.trace(_traceLevels.networkCat, s); - } - } + buf.position(pos + ret); } - catch(java.io.InterruptedIOException ex) + } + catch(java.io.InterruptedIOException ex) + { + if(ex.bytesTransferred > 0) { - continue; + buf.position(pos + ex.bytesTransferred); } - catch(java.io.IOException ex) + if(timeout >= 0) { - if(Network.connectionLost(ex)) + if(interval >= timeout) { - Ice.ConnectionLostException se = new Ice.ConnectionLostException(); - se.initCause(ex); - throw se; + throw new Ice.TimeoutException(); } - - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; + timeout -= interval; } } - } - finally - { - if(selector != null) + catch(java.io.IOException ex) { - try + if(Network.connectionLost(ex)) { - selector.close(); - } - catch(java.io.IOException ex) - { - // Ignore. + Ice.ConnectionLostException se = new Ice.ConnectionLostException(); + se.initCause(ex); + throw se; } + + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; } } + + if(_shutdown) + { + throw new Ice.ConnectionLostException(); + } } public String @@ -331,25 +214,48 @@ final class TcpTransceiver implements Transceiver // // Only for use by TcpConnector, TcpAcceptor // - TcpTransceiver(Instance instance, java.nio.channels.SocketChannel fd) + TcpTransceiver(Instance instance, java.net.Socket fd) { _fd = fd; _traceLevels = instance.traceLevels(); _logger = instance.logger(); _desc = Network.fdToString(_fd); + try + { + _in = _fd.getInputStream(); + _out = _fd.getOutputStream(); + } + catch(java.io.IOException ex) + { + try + { + _fd.close(); + } + catch(java.io.IOException e) + { + } + _fd = null; + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + _shutdown = false; } protected synchronized void finalize() throws Throwable { - assert(_fd == null); + IceUtil.Assert.FinalizerAssert(_fd == null); super.finalize(); } - private java.nio.channels.SocketChannel _fd; + private java.net.Socket _fd; private TraceLevels _traceLevels; private Ice.Logger _logger; private String _desc; + private java.io.InputStream _in; + private java.io.OutputStream _out; + private volatile boolean _shutdown; } diff --git a/javae/src/IceInternal/Transceiver.java b/javae/src/IceInternal/Transceiver.java index ea8c8a30096..a1217edeae0 100644 --- a/javae/src/IceInternal/Transceiver.java +++ b/javae/src/IceInternal/Transceiver.java @@ -11,7 +11,6 @@ package IceInternal; public interface Transceiver { - java.nio.channels.SelectableChannel fd(); void close(); void shutdownWrite(); void shutdownReadWrite(); diff --git a/javae/test/IceE/location/Client.java b/javae/test/IceE/location/Client.java index c812365ead7..d127f5e1e64 100644 --- a/javae/test/IceE/location/Client.java +++ b/javae/test/IceE/location/Client.java @@ -26,6 +26,14 @@ public class Client { Ice.Properties properties = Ice.Util.createProperties(args); properties.setProperty("Ice.Default.Locator", "locator:default -p 12345"); + // + // This test requires an extra retry interval because it is possible for + // a proxy to encounter two CloseConnectionExceptions in a row during + // retries. The first is raised by an already-closed connection, and the + // second occurs when a CloseConnection message is pending on the next + // connection that is tried. + // + properties.setProperty("Ice.RetryIntervals", "0 0"); communicator = Ice.Util.initializeWithProperties(args, properties); status = run(args, communicator); } |