private void finish() { if(!_initialized) { if(_instance.traceLevels().network >= 2) { StringBuilder s = new StringBuilder("failed to "); s.Append(_connector != null ? "establish" : "accept"); s.Append(" "); s.Append(_endpoint.protocol()); s.Append(" connection\n"); s.Append(ToString()); s.Append("\n"); s.Append(_exception); _instance.initializationData().logger.trace(_instance.traceLevels().networkCat, s.ToString()); } } else { if(_instance.traceLevels().network >= 1) { StringBuilder s = new StringBuilder("closed "); s.Append(_endpoint.protocol()); s.Append(" connection\n"); s.Append(ToString()); // // Trace the cause of unexpected connection closures // if(!(_exception is CloseConnectionException || _exception is ForcedCloseConnectionException || _exception is ConnectionTimeoutException || _exception is CommunicatorDestroyedException || _exception is ObjectAdapterDeactivatedException)) { s.Append("\n"); s.Append(_exception); } _instance.initializationData().logger.trace(_instance.traceLevels().networkCat, s.ToString()); } } if(_startCallback != null) { _startCallback.connectionStartFailed(this, _exception); _startCallback = null; } if(_sendStreams.Count > 0) { if(!_writeStream.isEmpty()) { // // Return the stream to the outgoing call. This is important for // retriable AMI calls which are not marshalled again. // OutgoingMessage message = _sendStreams.First.Value; _writeStream.swap(message.stream); // // The current message might be sent but not yet removed from _sendStreams. If // the response has been received in the meantime, we remove the message from // _sendStreams to not call finished on a message which is already done. // if(message.isSent || message.receivedReply) { if(message.sent() && message.invokeSent) { message.outAsync.invokeSent(); } if(message.receivedReply) { IceInternal.OutgoingAsync outAsync = (IceInternal.OutgoingAsync)message.outAsync; if(outAsync.response()) { outAsync.invokeResponse(); } } _sendStreams.RemoveFirst(); } } foreach (OutgoingMessage o in _sendStreams) { o.completed(_exception); if(o.requestId > 0) // Make sure finished isn't called twice. { _asyncRequests.Remove(o.requestId); } } _sendStreams.Clear(); // Must be cleared before _requests because of Outgoing* references in OutgoingMessage } foreach(IceInternal.OutgoingAsyncBase o in _asyncRequests.Values) { if(o.exception(_exception)) { o.invokeException(); } } _asyncRequests.Clear(); // // Don't wait to be reaped to reclaim memory allocated by read/write streams. // _writeStream.clear(); _writeStream.getBuffer().clear(); _readStream.clear(); _readStream.getBuffer().clear(); _incomingCache = null; if(_closeCallback != null) { try { _closeCallback(this); } catch(System.Exception ex) { _logger.error("connection callback exception:\n" + ex + '\n' + _desc); } _closeCallback = null; } _heartbeatCallback = null; // // This must be done last as this will cause waitUntilFinished() to return (and communicator // objects such as the timer might be destroyed too). // lock(this) { setState(StateFinished); if(_dispatchCount == 0) { reap(); } } }
public void setHeartbeatCallback(HeartbeatCallback callback) { lock(this) { _heartbeatCallback = callback; } }