Пример #1
0
        /// <summary>
        /// Queues a service name registration for the connection.
        /// </summary>
        /// <param name="serviceName">Name of the service.</param>
        /// <param name="onAquired">Action invoked when the service name is assigned to the connection.</param>
        /// <param name="onLost">Action invoked when the service name is no longer assigned to the connection.</param>
        /// <param name="options">Options for the registration.</param>
        /// <exception cref="ObjectDisposedException">The connection has been disposed.</exception>
        /// <exception cref="InvalidOperationException">The operation is invalid in the current state.</exception>
        /// <exception cref="DisconnectedException">The connection was closed after it was established.</exception>
        /// <exception cref="DBusException">Error returned by remote peer.</exception>
        /// <exception cref="ProtocolException">Unexpected reply.</exception>
        /// <remarks>
        /// This operation is not supported for AutoConnection connections.
        /// </remarks>
        public async Task QueueServiceRegistrationAsync(string serviceName, Action onAquired = null, Action onLost = null, ServiceRegistrationOptions options = ServiceRegistrationOptions.Default)
        {
            CheckNotConnectionType(ConnectionType.ClientAutoConnect);
            var connection = GetConnectedConnection();

            if (!options.HasFlag(ServiceRegistrationOptions.AllowReplacement) && (onLost != null))
            {
                throw new ArgumentException($"{nameof(onLost)} can only be set when {nameof(ServiceRegistrationOptions.AllowReplacement)} is also set", nameof(onLost));
            }

            RequestNameOptions requestOptions = RequestNameOptions.None;

            if (options.HasFlag(ServiceRegistrationOptions.ReplaceExisting))
            {
                requestOptions |= RequestNameOptions.ReplaceExisting;
            }
            if (options.HasFlag(ServiceRegistrationOptions.AllowReplacement))
            {
                requestOptions |= RequestNameOptions.AllowReplacement;
            }
            var reply = await connection.RequestNameAsync(serviceName, requestOptions, onAquired, onLost, CaptureSynchronizationContext());

            switch (reply)
            {
            case RequestNameReply.PrimaryOwner:
            case RequestNameReply.InQueue:
                return;

            case RequestNameReply.Exists:
            case RequestNameReply.AlreadyOwner:
            default:
                throw new ProtocolException("Unexpected reply");
            }
        }
Пример #2
0
        public async Task <RequestNameReply> RequestNameAsync(string name, RequestNameOptions options, Action onAquired, Action onLost, SynchronizationContext synchronzationContext)
        {
            lock (_gate)
            {
                ThrowIfNotConnected();
                ThrowIfRemoteIsNotBus();

                if (_serviceNameRegistrations.ContainsKey(name))
                {
                    throw new InvalidOperationException("The name is already requested");
                }
                _serviceNameRegistrations[name] = new ServiceNameRegistration
                {
                    OnAquire = onAquired,
                    OnLost   = onLost,
                    SynchronizationContext = synchronzationContext
                };
            }
            try
            {
                var reply = await CallRequestNameAsync(name, options);

                return(reply);
            }
            catch
            {
                lock (_gate)
                {
                    _serviceNameRegistrations.Remove(name);
                }
                throw;
            }
        }
Пример #3
0
        private async Task <RequestNameReply> CallRequestNameAsync(string name, RequestNameOptions options)
        {
            var writer = new MessageWriter();

            writer.WriteString(name);
            writer.WriteUInt32((uint)options);

            Message callMsg = new Message(
                new Header(MessageType.MethodCall)
            {
                Path        = DBusObjectPath,
                Interface   = DBusInterface,
                Member      = "RequestName",
                Destination = DBusServiceName,
                Signature   = "su"
            },
                writer.ToArray(),
                writer.UnixFds
                );

            Message reply = await CallMethodAsync(callMsg, checkConnected : true, checkReplyType : true);

            var reader = new MessageReader(reply, null);
            var rv     = reader.ReadUInt32();

            return((RequestNameReply)rv);
        }
Пример #4
0
        /// <summary>
        /// Requests a service name to be assigned to the connection.
        /// </summary>
        /// <param name="serviceName">Name of the service.</param>
        /// <param name="onLost">Action invoked when the service name is no longer assigned to the connection.</param>
        /// <param name="options"></param>
        /// <exception cref="ObjectDisposedException">The connection has been disposed.</exception>
        /// <exception cref="InvalidOperationException">The operation is invalid in the current state.</exception>
        /// <exception cref="DisconnectedException">The connection was closed after it was established.</exception>
        /// <exception cref="DBusException">Error returned by remote peer.</exception>
        /// <remarks>
        /// This operation is not supported for AutoConnection connections.
        /// </remarks>
        public async Task RegisterServiceAsync(string serviceName, Action onLost = null, ServiceRegistrationOptions options = ServiceRegistrationOptions.Default)
        {
            CheckNotConnectionType(ConnectionType.ClientAutoConnect);
            var connection = GetConnectedConnection();

            if (!options.HasFlag(ServiceRegistrationOptions.AllowReplacement) && (onLost != null))
            {
                throw new ArgumentException($"{nameof(onLost)} can only be set when {nameof(ServiceRegistrationOptions.AllowReplacement)} is also set", nameof(onLost));
            }

            RequestNameOptions requestOptions = RequestNameOptions.DoNotQueue;

            if (options.HasFlag(ServiceRegistrationOptions.ReplaceExisting))
            {
                requestOptions |= RequestNameOptions.ReplaceExisting;
            }
            if (options.HasFlag(ServiceRegistrationOptions.AllowReplacement))
            {
                requestOptions |= RequestNameOptions.AllowReplacement;
            }
            var reply = await connection.RequestNameAsync(serviceName, requestOptions, null, onLost, CaptureSynchronizationContext()).ConfigureAwait(false);

            switch (reply)
            {
            case RequestNameReply.PrimaryOwner:
                return;

            case RequestNameReply.Exists:
                throw new InvalidOperationException("Service is registered by another connection");

            case RequestNameReply.AlreadyOwner:
                throw new InvalidOperationException("Service is already registered by this connection");

            case RequestNameReply.InQueue:
            default:
                throw new ProtocolException("Unexpected reply");
            }
        }