Esempio n. 1
0
        /// <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}'");
            }
        }
Esempio n. 2
0
 public NameOwnerWatcherRegistration(DBusConnection dbusConnection, string key, OwnerChangedMatchRule rule, Action <ServiceOwnerChangedEventArgs, Exception> handler)
 {
     _connection = dbusConnection;
     _rule       = rule;
     _handler    = handler;
     _key        = key;
 }
Esempio n. 3
0
        // 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);
        }
Esempio n. 4
0
        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();
                }
            }
        }
Esempio n. 5
0
 // 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;
     }
 }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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));
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
 public SignalHandlerRegistration(DBusConnection dbusConnection, SignalMatchRule rule, SignalHandler handler)
 {
     _connection = dbusConnection;
     _rule       = rule;
     _handler    = handler;
 }