/// <summary> /// Creates a new Connection with specific ConnectionOptions. /// </summary> /// <param name="connectionOptions"></param> public Connection(ConnectionOptions connectionOptions) { if (connectionOptions == null) { throw new ArgumentNullException(nameof(connectionOptions)); } _factory = new ProxyFactory(this); _synchronizationContext = connectionOptions.SynchronizationContext; if (connectionOptions is ClientConnectionOptions clientConnectionOptions) { _connectionType = clientConnectionOptions.AutoConnect ? ConnectionType.ClientAutoConnect : ConnectionType.ClientManual; _connectFunction = clientConnectionOptions.SetupAsync; _disposeAction = clientConnectionOptions.Teardown; } else if (connectionOptions is ServerConnectionOptions serverConnectionOptions) { _connectionType = ConnectionType.Server; _state = ConnectionState.Connected; _dbusConnection = new DBusConnection(localServer: true); _dbusConnectionTask = Task.FromResult(_dbusConnection); serverConnectionOptions.Connection = this; } else { throw new NotSupportedException($"Unknown ConnectionOptions type: '{typeof(ConnectionOptions).FullName}'"); } }
public NameOwnerWatcherRegistration(DBusConnection dbusConnection, string key, OwnerChangedMatchRule rule, Action <ServiceOwnerChangedEventArgs, Exception> handler) { _connection = dbusConnection; _rule = rule; _handler = handler; _key = key; }
// For testing internal static async Task <DBusConnection> CreateAndConnectAsync(IMessageStream stream, Action <Exception> onDisconnect = null) { var connection = new DBusConnection(stream); await connection.ConnectAsync(onDisconnect); return(connection); }
private void Disconnect(bool dispose, Exception exception) { lock (_gate) { if (dispose) { _disposed = true; } var previousState = _state; if (previousState == ConnectionState.Disconnecting || previousState == ConnectionState.Disconnected || previousState == ConnectionState.Created) { return; } _disconnectReason = exception; var connection = _dbusConnection; var connectionCts = _connectCts;; var dbusConnectionTask = _dbusConnectionTask; var dbusConnectionTcs = _dbusConnectionTcs; var disposeUserToken = _disposeUserToken; _dbusConnection = null; _connectCts = null; _dbusConnectionTask = null; _dbusConnectionTcs = null; _disposeUserToken = NoDispose; foreach (var registeredObject in _registeredObjects) { registeredObject.Value.Unregister(); } _registeredObjects.Clear(); _state = ConnectionState.Disconnecting; EmitConnectionStateChanged(); connectionCts?.Cancel(); connectionCts?.Dispose(); dbusConnectionTcs?.SetException( dispose ? CreateDisposedException() : exception.GetType() == typeof(ConnectException) ? exception : new DisconnectedException(exception)); connection?.Disconnect(dispose, exception); if (disposeUserToken != NoDispose) { _disposeAction?.Invoke(disposeUserToken); } if (_state == ConnectionState.Disconnecting) { _state = ConnectionState.Disconnected; EmitConnectionStateChanged(); } } }
// Used by tests internal void Connect(DBusConnection dbusConnection) { lock (_gate) { if (_state != ConnectionState.Created) { throw new InvalidOperationException("Can only connect once"); } _dbusConnection = dbusConnection; _dbusConnectionTask = Task.FromResult(_dbusConnection); _state = ConnectionState.Connected; } }
public static async Task <DBusConnection> CreateAndConnectAsync(IMessageStream stream, Action <Exception> onDisconnect, IEnumerable <IClientObjectProvider> clientProviders, bool sayHelloToServer = true, TimeSpan?initialTimeout = null) { var dbusConnection = new DBusConnection(stream, clientProviders); if (initialTimeout.HasValue) { dbusConnection.Timeout = initialTimeout.Value; } foreach (var prov in clientProviders) { prov.DBusConnection = dbusConnection; } await dbusConnection.ConnectAsync(onDisconnect, default(CancellationToken), sayHelloToServer); return(dbusConnection); }
public static async Task <DBusConnection> ConnectAsync(ClientSetupResult connectionContext, Action <Exception> onDisconnect, CancellationToken cancellationToken) { var _entries = AddressEntry.ParseEntries(connectionContext.ConnectionAddress); if (_entries.Length == 0) { throw new ArgumentException("No addresses were found", nameof(connectionContext.ConnectionAddress)); } Guid _serverId = Guid.Empty; IMessageStream stream = null; var index = 0; while (index < _entries.Length) { AddressEntry entry = _entries[index++]; _serverId = entry.Guid; try { stream = await Transport.ConnectAsync(entry, connectionContext, cancellationToken).ConfigureAwait(false); } catch { if (index < _entries.Length) { continue; } throw; } break; } return(await DBusConnection.CreateAndConnectAsync(stream, onDisconnect)); }
private async Task <DBusConnection> DoConnectAsync() { Task <DBusConnection> connectionTask = null; bool alreadyConnecting = false; lock (_gate) { if (_disposed) { ThrowDisposed(); } if (_connectionType == ConnectionType.ClientManual) { if (_state != ConnectionState.Created) { throw new InvalidOperationException("Can only connect once"); } } else { if (_state == ConnectionState.Connecting || _state == ConnectionState.Connected) { connectionTask = _dbusConnectionTask; alreadyConnecting = true; } } if (!alreadyConnecting) { _connectCts = new CancellationTokenSource(); _dbusConnectionTcs = new TaskCompletionSource <DBusConnection>(); _dbusConnectionTask = _dbusConnectionTcs.Task; connectionTask = _dbusConnectionTask; _state = ConnectionState.Connecting; EmitConnectionStateChanged(); } } if (alreadyConnecting) { return(await connectionTask); } DBusConnection connection; object disposeUserToken = NoDispose; try { ClientSetupResult connectionContext = await _connectFunction(); disposeUserToken = connectionContext.TeardownToken; connection = await DBusConnection.ConnectAsync(connectionContext, OnDisconnect, _connectCts.Token); } catch (ConnectException ce) { if (disposeUserToken != NoDispose) { _disposeAction?.Invoke(disposeUserToken); } Disconnect(dispose: false, exception: ce); throw; } catch (Exception e) { if (disposeUserToken != NoDispose) { _disposeAction?.Invoke(disposeUserToken); } var ce = new ConnectException(e.Message, e); Disconnect(dispose: false, exception: ce); throw ce; } lock (_gate) { if (_state == ConnectionState.Connecting) { _disposeUserToken = disposeUserToken; _dbusConnection = connection; _connectCts.Dispose(); _connectCts = null; _state = ConnectionState.Connected; _dbusConnectionTcs.SetResult(connection); _dbusConnectionTcs = null; EmitConnectionStateChanged(); } else { connection.Dispose(); if (disposeUserToken != NoDispose) { _disposeAction?.Invoke(disposeUserToken); } } ThrowIfNotConnected(); } return(connection); }
public SignalHandlerRegistration(DBusConnection dbusConnection, SignalMatchRule rule, SignalHandler handler) { _connection = dbusConnection; _rule = rule; _handler = handler; }