// 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); }
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); }
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); }