private void ChangeState(ConnectionContext ctx, TsClientStatus setStatus, CommandError?error = null) { scheduler.VerifyOwnThread(); if (ctx != context) { Log.Debug("Stray disconnect from old packethandler"); } Log.Debug("ChangeState {0} -> {1} (error:{2})", status, setStatus, error?.ErrorFormat() ?? "none"); switch ((status, setStatus)) { case (TsClientStatus.Disconnected, TsClientStatus.Disconnected): // Already disconnected, do nothing break; case (TsClientStatus.Disconnected, TsClientStatus.Connecting): status = TsClientStatus.Connecting; break; case (TsClientStatus.Connecting, TsClientStatus.Connected): status = TsClientStatus.Connected; ctx.ConnectEvent.SetResult(R.Ok); break; case (TsClientStatus.Connecting, TsClientStatus.Disconnected): case (TsClientStatus.Connected, TsClientStatus.Disconnected): case (TsClientStatus.Disconnecting, TsClientStatus.Disconnected): status = TsClientStatus.Disconnected; ctx.PacketHandler.Stop(); msgProc.DropQueue(); var statusBefore = status; context = null; if (statusBefore == TsClientStatus.Connecting) { ctx.ConnectEvent.SetResult(error ?? CommandError.ConnectionClosed); // TODO: Set exception maybe ? } ctx.DisconnectEvent.SetResult(null); OnDisconnected?.Invoke(this, new DisconnectEventArgs(ctx.ExitReason ?? Reason.LeftServer, error)); break; case (TsClientStatus.Connected, TsClientStatus.Disconnecting): status = TsClientStatus.Disconnecting; break; default: Trace.Fail($"Invalid transition change from {status} to {setStatus}"); break; } }
private void DisconnectInternal(ConnectionContext ctx, CommandError error = null, TsClientStatus?setStatus = null) { bool triggerEventSafe = false; lock (statusLock) { Log.Debug("DisconnectInternal wasExit:{0} error:{1} oldStatus:{2} newStatus:{3}", ctx.WasExit, error?.ErrorFormat(), status, setStatus); if (setStatus.HasValue) { status = setStatus.Value; } if (ctx.WasExit) { return; } switch (status) { case TsClientStatus.Connecting: case TsClientStatus.Disconnected: ctx.WasExit = true; packetHandler.Stop(); msgProc.DropQueue(); dispatcher.Dispose(); dispatcher = null; triggerEventSafe = true; break; case TsClientStatus.Disconnecting: break; case TsClientStatus.Connected: ClientDisconnect(Reason.LeftServer, QuitMessage); status = TsClientStatus.Disconnecting; break; default: throw Tools.UnhandledDefault(status); } } if (triggerEventSafe) { OnDisconnected?.Invoke(this, new DisconnectEventArgs(ctx.ExitReason ?? Reason.LeftServer, error)); } }