diff options
-rw-r--r-- | cs/CHANGES | 3 | ||||
-rwxr-xr-x | cs/src/Ice/BasicStream.cs | 53 | ||||
-rwxr-xr-x | cs/src/Ice/ConnectionI.cs | 6 | ||||
-rwxr-xr-x | cs/src/Ice/Incoming.cs | 34 | ||||
-rwxr-xr-x | cs/src/Ice/Outgoing.cs | 13 | ||||
-rw-r--r-- | cs/src/Ice/Proxy.cs | 4 | ||||
-rw-r--r-- | java/CHANGES | 7 | ||||
-rw-r--r-- | java/src/Ice/ConnectionI.java | 327 | ||||
-rw-r--r-- | java/src/Ice/_ObjectDelM.java | 4 | ||||
-rw-r--r-- | java/src/IceInternal/BasicStream.java | 65 | ||||
-rw-r--r-- | java/src/IceInternal/Incoming.java | 14 | ||||
-rw-r--r-- | java/src/IceInternal/IncomingBase.java | 31 | ||||
-rw-r--r-- | java/src/IceInternal/Outgoing.java | 15 |
13 files changed, 323 insertions, 253 deletions
diff --git a/cs/CHANGES b/cs/CHANGES index f17568b685b..de893ba2208 100644 --- a/cs/CHANGES +++ b/cs/CHANGES @@ -1,6 +1,9 @@ Changes since version 2.1.0 --------------------------- +- Modified the Ice marshaling engine so that references to Ice objects + are released as soon as possible. + - Fixed a race condition in the Ice run time that could cause a NullPointerException during process shutdown on machines with more than one CPU. diff --git a/cs/src/Ice/BasicStream.cs b/cs/src/Ice/BasicStream.cs index bfe5058607a..2cb6d1a96cc 100755 --- a/cs/src/Ice/BasicStream.cs +++ b/cs/src/Ice/BasicStream.cs @@ -84,6 +84,7 @@ namespace IceInternal _readEncapsStack.next = _readEncapsCache; _readEncapsCache = _readEncapsStack; _readEncapsStack = null; + _readEncapsCache.reset(); } if(_objectList != null) @@ -346,14 +347,7 @@ namespace IceInternal 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(); - } + curr.reset(); _writeEncapsCache = _writeEncapsCache.next; } else @@ -377,12 +371,11 @@ namespace IceInternal 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; - } + WriteEncaps curr = _writeEncapsStack; + _writeEncapsStack = curr.next; + curr.next = _writeEncapsCache; + _writeEncapsCache = curr; + _writeEncapsCache.reset(); } public virtual void startReadEncaps() @@ -391,13 +384,7 @@ namespace IceInternal ReadEncaps curr = _readEncapsCache; if(curr != null) { - if(curr.patchMap != null) - { - curr.patchMap.Clear(); - curr.unmarshaledMap.Clear(); - curr.typeIdIndex = 0; - curr.typeIdMap.Clear(); - } + curr.reset(); _readEncapsCache = _readEncapsCache.next; } else @@ -463,6 +450,7 @@ namespace IceInternal _readEncapsStack = curr.next; curr.next = _readEncapsCache; _readEncapsCache = curr; + _readEncapsCache.reset(); } public virtual void checkReadEncaps() @@ -1970,6 +1958,17 @@ namespace IceInternal internal int typeIdIndex; internal Hashtable typeIdMap; internal ReadEncaps next; + + internal void reset() + { + if(patchMap != null) + { + patchMap.Clear(); + unmarshaledMap.Clear(); + typeIdIndex = 0; + typeIdMap.Clear(); + } + } } private sealed class WriteEncaps @@ -1982,6 +1981,18 @@ namespace IceInternal internal int typeIdIndex; internal Hashtable typeIdMap; internal WriteEncaps next; + + internal void reset() + { + if(toBeMarshaledMap != null) + { + writeIndex = 0; + toBeMarshaledMap.Clear(); + marshaledMap.Clear(); + typeIdIndex = 0; + typeIdMap.Clear(); + } + } } private ReadEncaps _readEncapsStack; diff --git a/cs/src/Ice/ConnectionI.cs b/cs/src/Ice/ConnectionI.cs index 8a1cc331c50..f5ed79a9f59 100755 --- a/cs/src/Ice/ConnectionI.cs +++ b/cs/src/Ice/ConnectionI.cs @@ -1812,6 +1812,10 @@ namespace Ice { inc.next = _incomingCache; _incomingCache = inc; + // + // Clear references to Ice objects as soon as possible. + // + _incomingCache.reclaim(); } } @@ -1819,7 +1823,7 @@ namespace Ice private string _desc; private string _type; private IceInternal.Endpoint _endpoint; - + private ObjectAdapter _adapter; private IceInternal.ServantManager _servantManager; diff --git a/cs/src/Ice/Incoming.cs b/cs/src/Ice/Incoming.cs index a8fed6d7e86..c422a490f49 100755 --- a/cs/src/Ice/Incoming.cs +++ b/cs/src/Ice/Incoming.cs @@ -59,8 +59,7 @@ namespace IceInternal } // - // This function allows this object to be reused, rather than - // reallocated. + // These functions allow this object to be reused, rather than reallocated. // public virtual void reset(Instance instance, Ice.ConnectionI connection, Ice.ObjectAdapter adapter, bool response, byte compress) @@ -77,7 +76,7 @@ namespace IceInternal _locator = null; - _cookie = null; + Debug.Assert(_cookie == null); _response = response; @@ -87,14 +86,20 @@ namespace IceInternal { _os = new BasicStream(instance); } - else + + _connection = connection; + } + + public virtual void reclaim() + { + _cookie = null; + + if(_os != null) { _os.reset(); } - - _connection = connection; } - + protected internal void __warning(System.Exception ex) { Debug.Assert(_os != null); @@ -134,8 +139,7 @@ namespace IceInternal } // - // This function allows this object to be reused, rather than - // reallocated. + // These functions allow this object to be reused, rather than reallocated. // public override void reset(Instance instance, Ice.ConnectionI connection, Ice.ObjectAdapter adapter, bool response, byte compress) @@ -144,14 +148,20 @@ namespace IceInternal { _is = new BasicStream(instance); } - else + + base.reset(instance, connection, adapter, response, compress); + } + + public override void reclaim() + { + if(_is != null) { _is.reset(); } - base.reset(instance, connection, adapter, response, compress); + base.reclaim(); } - + public void invoke(ServantManager servantManager) { // diff --git a/cs/src/Ice/Outgoing.cs b/cs/src/Ice/Outgoing.cs index ec9d75343e6..d3f89392e90 100755 --- a/cs/src/Ice/Outgoing.cs +++ b/cs/src/Ice/Outgoing.cs @@ -29,21 +29,20 @@ namespace IceInternal } // - // This function allows this object to be reused, rather than - // reallocated. + // These functions allow this object to be reused, rather than reallocated. // public void reset(string operation, Ice.OperationMode mode, Ice.Context context) { _state = StateUnsent; _exception = null; - Debug.Assert(_is != null); - _is.reset(); + writeHeader(operation, mode, context); + } - Debug.Assert(_os != null); + public void reclaim() + { + _is.reset(); _os.reset(); - - writeHeader(operation, mode, context); } // Returns true if ok, false if user exception. diff --git a/cs/src/Ice/Proxy.cs b/cs/src/Ice/Proxy.cs index 4cf79fa517f..cf23109afc2 100644 --- a/cs/src/Ice/Proxy.cs +++ b/cs/src/Ice/Proxy.cs @@ -1154,6 +1154,10 @@ namespace Ice { outg.next = __outgoingCache; __outgoingCache = outg; + // + // Clear references to Ice objects as soon as possible. + // + __outgoingCache.reclaim(); } } diff --git a/java/CHANGES b/java/CHANGES index 3a09e38fd69..b105e101b3a 100644 --- a/java/CHANGES +++ b/java/CHANGES @@ -1,8 +1,11 @@ Changes since version 2.1.0 --------------------------- -- Fixed a race condition that could cause a process to abort - during shutdown. +- Modified the Ice marshaling engine so that references to Ice objects + are released as soon as possible. + +- Fixed a race condition that could cause a process to abort during + shutdown. - Added sequences of fixed-length elements to throughput demo. diff --git a/java/src/Ice/ConnectionI.java b/java/src/Ice/ConnectionI.java index e40a03af2b3..a88a31002fa 100644 --- a/java/src/Ice/ConnectionI.java +++ b/java/src/Ice/ConnectionI.java @@ -2039,6 +2039,8 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne boolean closed = false; + IceInternal.BasicStream stream = new IceInternal.BasicStream(_instance); + while(!closed) { // @@ -2046,202 +2048,207 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // 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); - if(pos != stream.size()) - { - if(_endpoint.datagram()) + 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]) { - if(warnUdp) - { - _logger.warning("DatagramLimitException: maximum size of " + pos + " exceeded"); - } - throw new DatagramLimitException(); + BadMagicException ex = new BadMagicException(); + ex.badMagic = m; + throw ex; } - else + byte pMajor = stream.readByte(); + byte pMinor = stream.readByte(); + if(pMajor != IceInternal.Protocol.protocolMajor) { - _transceiver.read(stream, -1); - assert(stream.pos() == stream.size()); + 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; } - } - } - catch(DatagramLimitException ex) // Expected. - { - continue; - } - catch(LocalException ex) - { - exception(ex); - } - - MessageInfo info = new MessageInfo(stream); - - LocalException exception = null; - - IceInternal.IntMap requests = null; - IceInternal.IntMap asyncRequests = null; - - synchronized(this) - { - while(_state == StateHolding) - { - try + byte eMajor = stream.readByte(); + byte eMinor = stream.readByte(); + if(eMajor != IceInternal.Protocol.encodingMajor) { - wait(); + 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(); } - catch(InterruptedException ex) + if(size > _instance.messageSizeMax()) { + throw new MemoryLimitException(); + } + if(size > stream.size()) + { + stream.resize(size, true); + } + stream.pos(pos); + + if(pos != stream.size()) + { + if(_endpoint.datagram()) + { + if(warnUdp) + { + _logger.warning("DatagramLimitException: maximum size of " + pos + " exceeded"); + } + throw new DatagramLimitException(); + } + else + { + _transceiver.read(stream, -1); + assert(stream.pos() == stream.size()); + } } } - - if(_state != StateClosed) + catch(DatagramLimitException ex) // Expected. + { + continue; + } + catch(LocalException ex) { - parseMessage(info); + exception(ex); } - // - // parseMessage() can close the connection, so we must - // check for closed state again. - // - if(_state == StateClosed) + MessageInfo info = new MessageInfo(stream); + + LocalException exception = null; + + IceInternal.IntMap requests = null; + IceInternal.IntMap asyncRequests = null; + + synchronized(this) { - // - // We must make sure that nobody is sending when we close - // the transceiver. - // - synchronized(_sendMutex) + while(_state == StateHolding) { try { - _transceiver.close(); + wait(); } - catch(LocalException ex) + catch(InterruptedException ex) { - exception = ex; } - - _transceiver = null; - notifyAll(); + } + + if(_state != StateClosed) + { + parseMessage(info); } // - // We cannot simply return here. We have to make sure - // that all requests (regular and async) are notified - // about the closed connection below. + // parseMessage() can close the connection, so we must + // check for closed state again. // - closed = true; - } + if(_state == StateClosed) + { + // + // We must make sure that nobody is sending when we close + // the transceiver. + // + synchronized(_sendMutex) + { + try + { + _transceiver.close(); + } + catch(LocalException ex) + { + exception = ex; + } + + _transceiver = null; + notifyAll(); + } - if(_state == StateClosed || _state == StateClosing) - { - requests = _requests; - _requests = new IceInternal.IntMap(); + // + // We cannot simply return here. We have to make sure + // that all requests (regular and async) are notified + // about the closed connection below. + // + closed = true; + } - asyncRequests = _asyncRequests; - _asyncRequests = new IceInternal.IntMap(); + if(_state == StateClosed || _state == StateClosing) + { + requests = _requests; + _requests = new IceInternal.IntMap(); + + asyncRequests = _asyncRequests; + _asyncRequests = new IceInternal.IntMap(); + } } - } - // - // Asynchronous replies must be handled outside the thread - // synchronization, so that nested calls are possible. - // - if(info.outAsync != null) - { - info.outAsync.__finished(info.stream); - } - - // - // Method invocation (or multiple invocations for batch messages) - // must be done outside the thread synchronization, so that nested - // calls are possible. - // - invokeAll(info.stream, info.invokeNum, info.requestId, info.compress, info.servantManager, - info.adapter); + // + // Asynchronous replies must be handled outside the thread + // synchronization, so that nested calls are possible. + // + if(info.outAsync != null) + { + info.outAsync.__finished(info.stream); + } + + // + // Method invocation (or multiple invocations for batch messages) + // must be done outside the thread synchronization, so that nested + // calls are possible. + // + invokeAll(info.stream, info.invokeNum, info.requestId, info.compress, info.servantManager, + info.adapter); - if(requests != null) - { - java.util.Iterator i = requests.entryIterator(); - while(i.hasNext()) + if(requests != null) { - IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); - IceInternal.Outgoing out = (IceInternal.Outgoing)e.getValue(); - out.finished(_exception); // The exception is immutable at this point. + java.util.Iterator i = requests.entryIterator(); + while(i.hasNext()) + { + IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); + IceInternal.Outgoing out = (IceInternal.Outgoing)e.getValue(); + out.finished(_exception); // The exception is immutable at this point. + } } - } - if(asyncRequests != null) - { - java.util.Iterator i = asyncRequests.entryIterator(); - while(i.hasNext()) + if(asyncRequests != null) { - IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); - IceInternal.OutgoingAsync out = (IceInternal.OutgoingAsync)e.getValue(); - out.__finished(_exception); // The exception is immutable at this point. + java.util.Iterator i = asyncRequests.entryIterator(); + while(i.hasNext()) + { + IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); + IceInternal.OutgoingAsync out = (IceInternal.OutgoingAsync)e.getValue(); + out.__finished(_exception); // The exception is immutable at this point. + } } - } - if(exception != null) + if(exception != null) + { + assert(closed); + throw exception; + } + } + finally { - assert(closed); - throw exception; - } + stream.reset(); + } } } @@ -2282,7 +2289,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { in = _incomingCache; _incomingCache = _incomingCache.next; - in.reset(_instance, this, adapter, response, compress); + in.reset(_instance, this, adapter, response, compress); in.next = null; } } @@ -2297,6 +2304,10 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { in.next = _incomingCache; _incomingCache = in; + // + // Clear references to Ice objects as soon as possible. + // + _incomingCache.reclaim(); } } diff --git a/java/src/Ice/_ObjectDelM.java b/java/src/Ice/_ObjectDelM.java index 82695e5d7b5..e725a3af04b 100644 --- a/java/src/Ice/_ObjectDelM.java +++ b/java/src/Ice/_ObjectDelM.java @@ -231,6 +231,10 @@ public class _ObjectDelM implements _ObjectDel { out.next = __outgoingCache; __outgoingCache = out; + // + // Clear references to Ice objects as soon as possible. + // + __outgoingCache.reclaim(); } } diff --git a/java/src/IceInternal/BasicStream.java b/java/src/IceInternal/BasicStream.java index 5f73daf1611..e4555a5ac85 100644 --- a/java/src/IceInternal/BasicStream.java +++ b/java/src/IceInternal/BasicStream.java @@ -52,6 +52,7 @@ public class BasicStream _readEncapsStack.next = _readEncapsCache; _readEncapsCache = _readEncapsStack; _readEncapsStack = null; + _readEncapsCache.reset(); } if(_objectList != null) @@ -321,14 +322,7 @@ public class BasicStream 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(); - } + curr.reset(); _writeEncapsCache = _writeEncapsCache.next; } else @@ -353,12 +347,11 @@ 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; - } + WriteEncaps curr = _writeEncapsStack; + _writeEncapsStack = curr.next; + curr.next = _writeEncapsCache; + _writeEncapsCache = curr; + _writeEncapsCache.reset(); } public void @@ -368,13 +361,7 @@ public class BasicStream ReadEncaps curr = _readEncapsCache; if(curr != null) { - if(curr.patchMap != null) - { - curr.patchMap.clear(); - curr.unmarshaledMap.clear(); - curr.typeIdIndex = 0; - curr.typeIdMap.clear(); - } + curr.reset(); _readEncapsCache = _readEncapsCache.next; } else @@ -436,12 +423,11 @@ public class BasicStream throw new Ice.UnmarshalOutOfBoundsException(); } - { - ReadEncaps curr = _readEncapsStack; - _readEncapsStack = curr.next; - curr.next = _readEncapsCache; - _readEncapsCache = curr; - } + ReadEncaps curr = _readEncapsStack; + _readEncapsStack = curr.next; + curr.next = _readEncapsCache; + _readEncapsCache = curr; + _readEncapsCache.reset(); } public void @@ -2257,6 +2243,18 @@ public class BasicStream int typeIdIndex; java.util.TreeMap typeIdMap; ReadEncaps next; + + void + reset() + { + if(patchMap != null) + { + patchMap.clear(); + unmarshaledMap.clear(); + typeIdIndex = 0; + typeIdMap.clear(); + } + } } private static final class WriteEncaps @@ -2269,6 +2267,19 @@ public class BasicStream int typeIdIndex; java.util.TreeMap typeIdMap; WriteEncaps next; + + void + reset() + { + if(toBeMarshaledMap != null) + { + writeIndex = 0; + toBeMarshaledMap.clear(); + marshaledMap.clear(); + typeIdIndex = 0; + typeIdMap.clear(); + } + } } private ReadEncaps _readEncapsStack; diff --git a/java/src/IceInternal/Incoming.java b/java/src/IceInternal/Incoming.java index 6f48fd124a5..6a61a8063c4 100644 --- a/java/src/IceInternal/Incoming.java +++ b/java/src/IceInternal/Incoming.java @@ -20,8 +20,7 @@ final public class Incoming extends IncomingBase } // - // This function allows this object to be reused, rather than - // reallocated. + // These functions allow this object to be reused, rather than reallocated. // public void reset(Instance instance, Ice.ConnectionI connection, Ice.ObjectAdapter adapter, boolean response, byte compress) @@ -30,12 +29,19 @@ final public class Incoming extends IncomingBase { _is = new BasicStream(instance); } - else + + super.reset(instance, connection, adapter, response, compress); + } + + public void + reclaim() + { + if(_is != null) { _is.reset(); } - super.reset(instance, connection, adapter, response, compress); + super.reclaim(); } public void diff --git a/java/src/IceInternal/IncomingBase.java b/java/src/IceInternal/IncomingBase.java index 69d4393e410..1600b44fcc8 100644 --- a/java/src/IceInternal/IncomingBase.java +++ b/java/src/IceInternal/IncomingBase.java @@ -58,7 +58,7 @@ public class IncomingBase } // - // This function allows this object to be reused, rather than reallocated. + // These functions allow this object to be reused, rather than reallocated. // public void reset(Instance instance, Ice.ConnectionI connection, Ice.ObjectAdapter adapter, boolean response, byte compress) @@ -79,30 +79,33 @@ public class IncomingBase { _cookie = new Ice.LocalObjectHolder(); } - else - { - _cookie.value = null; - } _response = response; _compress = compress; - synchronized(this) + if(_os == null) { - if(_os == null) - { - _os = new BasicStream(instance); - } - else - { - _os.reset(); - } + _os = new BasicStream(instance); } _connection = connection; } + public void + reclaim() + { + if(_cookie != null) + { + _cookie.value = null; + } + + if(_os != null) + { + _os.reset(); + } + } + final protected void __warning(java.lang.Exception ex) { diff --git a/java/src/IceInternal/Outgoing.java b/java/src/IceInternal/Outgoing.java index 914944dc420..1371fc76e5b 100644 --- a/java/src/IceInternal/Outgoing.java +++ b/java/src/IceInternal/Outgoing.java @@ -27,7 +27,7 @@ public final class Outgoing } // - // This function allows this object to be reused, rather than + // These functions allow this object to be reused, rather than // reallocated. // public void @@ -37,15 +37,16 @@ public final class Outgoing _state = StateUnsent; _exception = null; - assert(_is != null); - _is.reset(); - - assert(_os != null); - _os.reset(); - writeHeader(operation, mode, context); } + public void + reclaim() + { + _is.reset(); + _os.reset(); + } + // Returns true if ok, false if user exception. public boolean invoke() |