private void setState(int state) { // // We don't want to send close connection messages if the endpoint // only supports oneway transmission from client to server. // if(_endpoint.datagram() && state == StateClosing) { state = StateClosed; } // // Skip graceful shutdown if we are destroyed before validation. // if(_state <= StateNotValidated && state == StateClosing) { state = StateClosed; } if(_state == state) // Don't switch twice. { return; } try { switch(state) { case StateNotInitialized: { Debug.Assert(false); break; } case StateNotValidated: { if(_state != StateNotInitialized) { Debug.Assert(_state == StateClosed); return; } break; } case StateActive: { // // Can only switch from holding or not validated to // active. // if(_state != StateHolding && _state != StateNotValidated) { return; } _threadPool.register(this, IceInternal.SocketOperation.Read); break; } case StateHolding: { // // Can only switch from active or not validated to // holding. // if(_state != StateActive && _state != StateNotValidated) { return; } if(_state == StateActive) { _threadPool.unregister(this, IceInternal.SocketOperation.Read); } break; } case StateClosing: case StateClosingPending: { // // Can't change back from closing pending. // if(_state >= StateClosingPending) { return; } break; } case StateClosed: { if(_state == StateFinished) { return; } _batchRequestQueue.destroy(_exception); _threadPool.finish(this); _transceiver.close(); break; } case StateFinished: { Debug.Assert(_state == StateClosed); _transceiver.destroy(); _communicator = null; break; } } } catch(Ice.LocalException ex) { _logger.error("unexpected connection exception:\n" + ex + "\n" + _transceiver.ToString()); } // // We only register with the connection monitor if our new state // is StateActive. Otherwise we unregister with the connection // monitor, but only if we were registered before, i.e., if our // old state was StateActive. // if(_monitor != null) { if(state == StateActive) { if(_acmLastActivity > -1) { _acmLastActivity = IceInternal.Time.currentMonotonicTimeMillis(); } _monitor.add(this); } else if(_state == StateActive) { _monitor.remove(this); } } if(_instance.initializationData().observer != null) { ConnectionState oldState = toConnectionState(_state); ConnectionState newState = toConnectionState(state); if(oldState != newState) { _observer = _instance.initializationData().observer.getConnectionObserver(initConnectionInfo(), _endpoint, newState, _observer); if(_observer != null) { _observer.attach(); } else { _writeStreamPos = -1; _readStreamPos = -1; } } if(_observer != null && state == StateClosed && _exception != null) { if(!(_exception is CloseConnectionException || _exception is ForcedCloseConnectionException || _exception is ConnectionTimeoutException || _exception is CommunicatorDestroyedException || _exception is ObjectAdapterDeactivatedException || (_exception is ConnectionLostException && _state >= StateClosing))) { _observer.failed(_exception.ice_id()); } } } _state = state; System.Threading.Monitor.PulseAll(this); if(_state == StateClosing && _dispatchCount == 0) { try { initiateShutdown(); } catch(LocalException ex) { setState(StateClosed, ex); } } }
public void updateObserver() { lock(this) { if(_state < StateNotValidated || _state > StateClosed) { return; } Debug.Assert(_instance.initializationData().observer != null); _observer = _instance.initializationData().observer.getConnectionObserver(initConnectionInfo(), _endpoint, toConnectionState(_state), _observer); if(_observer != null) { _observer.attach(); } else { _writeStreamPos = -1; _readStreamPos = -1; } } }