Exemplo n.º 1
0
        public Task <MessageTransaction> CallMethodAsync(Message msg, bool checkConnected, bool checkReplyType)
        {
            msg.Header.ReplyExpected = true;
            var serial = GenerateSerial();

            msg.Header.Serial = serial;

            var pending = new PendingMethodCont(msg, MethodCallTimeout);

            pending.Timer.Interval = Timeout.TotalMilliseconds;
            var pendingMethods = _pendingMethods;

            lock (_gate)
            {
                if (checkConnected || pendingMethods == null)
                {
                    ThrowIfNotConnected();
                }
                pendingMethods[msg.Header.Serial]   = pending;
                pending.Transaction.RequestSendTime = DateTime.Now;
                pending.Timer.Start();
            }
            // Chained (rather than async await) to preserve AsyncState
            SendMessageAsync(msg)
            .ContinueWith(r =>
            {
                if (r.IsFaulted || r.IsCanceled)
                {
                    pending.DisposeTimer();
                    pendingMethods = _pendingMethods;
                    lock (_gate)
                    {
                        pendingMethods.Remove(msg.Header.Serial);
                    }
                    pending.Transaction.RequestSendTime = null;
                    if (r.IsFaulted)
                    {
                        var ex = (r.Exception.InnerExceptions.Count == 1) ? r.Exception.InnerExceptions[0] : r.Exception;
                        pending.Reply.SetException(ex);
                    }
                    else
                    {
                        pending.Reply.SetCanceled();
                    }
                }
            });
            return(pending.Reply.Task);
        }
Exemplo n.º 2
0
        void MethodCallTimeout(PendingMethodCont cont)
        {
            var serialValue    = cont.Request.Header.Serial;
            var pendingMethods = _pendingMethods;

            cont.DisposeTimer();
            if (pendingMethods == null)
            {
                return;
            }
            bool setException;

            lock (_gate)
            {
                setException = pendingMethods.Remove(serialValue);
            }
            if (setException)
            {
                cont.Reply.TrySetException(new DBusException(DBusErrors.Timeout, "Did not receive a reply in time"));
            }
        }
Exemplo n.º 3
0
        private void HandleMessage(Message msg, IMessageStream peer)
        {
            uint?serial = msg.Header.ReplySerial;
            PendingMethodCont pending = null;
            var pendingMethods        = _pendingMethods;

            if (pendingMethods == null)
            {
                return; // Disposed
            }
            var receiveTime = DateTime.Now;

            if (serial != null)
            {
                uint serialValue = serial.Value;
                lock (_gate)
                {
                    if (pendingMethods.TryGetValue(serialValue, out pending))
                    {
                        pending.DisposeTimer();
                        pendingMethods.Remove(serialValue);
                    }
                }
                if (pending != null)
                {
                    pending.Transaction.ReplyReceivedTime = receiveTime;
                    pending.Transaction.Reply             = msg;
                    Exception ex = null;
                    switch (msg.Header.MessageType)
                    {
                    case MessageType.MethodReturn:
                        pending.Reply.TrySetResult(pending.Transaction);
                        break;

                    case MessageType.Error:
                        string errMsg = string.Empty;
                        if (msg.Header.Signature.Value.Value.StartsWith("s", StringComparison.Ordinal))
                        {
                            errMsg = new MessageReader(msg).ReadString();
                        }
                        ex = new DBusException(msg.Header.ErrorName, errMsg);
                        break;

                    case MessageType.Invalid:
                    default:
                        ex = new ProtocolException("Invalid message received: MessageType='" + msg.Header.MessageType + "'");
                        break;
                    }
                    if (ex != null)
                    {
                        pending.Reply.TrySetException(ex);
                    }
                }
                else
                {
                    serial = null;
                    // Drop quietly
                    //throw new ProtocolException("Unexpected reply message received: MessageType = '" + msg.Header.MessageType + "', ReplySerial = " + serialValue);
                }
            }

            var hook = MessageReceivedHook;

            if (hook != null)
            {
                var transaction = (pending != null) ? pending.Transaction : new MessageTransaction
                {
                    Reply             = msg,
                    ReplyReceivedTime = receiveTime
                };
                hook.Invoke(transaction);
            }
            if (serial != null)
            {
                return;
            }

            switch (msg.Header.MessageType)
            {
            case MessageType.MethodCall:
                HandleMethodCall(msg, peer);
                break;

            case MessageType.Signal:
                HandleSignal(msg);
                break;

            case MessageType.Error:
                string errMsg = string.Empty;
                if (msg.Header.Signature.Value.Value.StartsWith("s", StringComparison.Ordinal))
                {
                    errMsg = new MessageReader(msg).ReadString();
                }
                //throw new DBusException(msg.Header.ErrorName, errMsg);
                break;

            case MessageType.Invalid:
            default:
                //throw new ProtocolException("Invalid message received: MessageType='" + msg.Header.MessageType + "'");
                break;
            }
        }