示例#1
0
        public static void ReleaseAll(Delivery delivery, Error error)
        {
            Outcome outcome;
            if (error == null)
            {
                outcome = new Released();
            }
            else
            {
                outcome = new Rejected() { Error = error };
            }

            while (delivery != null)
            {
                if (delivery.OnOutcome != null)
                {
                    delivery.OnOutcome(delivery.Message, outcome, delivery.UserToken);
                }

                delivery.Buffer.ReleaseReference();
                delivery = (Delivery)delivery.Next;
            }
        }
示例#2
0
        internal void DisposeDelivery(bool role, Delivery delivery, DeliveryState state, bool settled)
        {
            Delivery current = null;
            lock (this.ThisLock)
            {
                LinkedList deliveryList = role ? this.incomingList : this.outgoingList;
                current = (Delivery)deliveryList.First;
                while (current != null)
                {
                    if (current == delivery)
                    {
                        if (settled)
                        {
                            deliveryList.Remove(current);
                        }

                        break;
                    }

                    current = (Delivery)current.Next;
                }
            }

            if (current != null)
            {
                current.Settled = settled;
                current.State = state;
                Dispose dispose = new Dispose()
                {
                    Role = role,
                    First = current.DeliveryId,
                    Settled = settled,
                    State = state
                };

                this.SendCommand(dispose);
            }
        }
示例#3
0
        void WriteDelivery(Delivery delivery)
        {
            while (delivery != null)
            {
                delivery.Handle = this.Handle;

                try
                {
                    bool settled = delivery.Settled;
                    this.Session.SendDelivery(delivery);
                    if (settled && delivery.OnOutcome != null)
                    {
                        delivery.OnOutcome(delivery.Message, new Accepted(), delivery.UserToken);
                    }
                }
                catch
                {
                    this.writing = false;
                    throw;
                }

                lock (this.ThisLock)
                {
                    delivery = (Delivery)this.outgoingList.First;
                    if (delivery == null)
                    {
                        this.writing = false;
                    }
                    else if (this.credit > 0)
                    {
                        this.outgoingList.Remove(delivery);
                        delivery.Tag = Delivery.GetDeliveryTag(this.deliveryCount);
                        this.credit--;
                        this.deliveryCount++;
                    }
                    else
                    {
                        delivery = null;
                        this.writing = false;
                    }
                }
            }
        }
示例#4
0
        internal void Send(Message message, DeliveryState deliveryState, OutcomeCallback callback, object state)
        {
            const int reservedBytes = 40;
            #if NETFX || NETFX40 || DOTNET
            var buffer = message.Encode(this.Session.Connection.BufferManager, reservedBytes);
            #else
            var buffer = message.Encode(reservedBytes);
            #endif
            if (buffer.Length < 1)
            {
                throw new ArgumentException("Cannot send an empty message.");
            }

            Delivery delivery = new Delivery()
            {
                Message = message,
                Buffer = buffer,
                ReservedBufferSize = reservedBytes,
                State = deliveryState,
                Link = this,
                OnOutcome = callback,
                UserToken = state,
                Settled = this.settleMode == SenderSettleMode.Settled || callback == null
            };

            lock (this.ThisLock)
            {
                this.ThrowIfDetaching("Send");

                if (this.credit <= 0 || this.writing)
                {
                    this.outgoingList.Add(delivery);
                    return;
                }

                delivery.Tag = Delivery.GetDeliveryTag(this.deliveryCount);
                this.credit--;
                this.deliveryCount++;
                this.writing = true;
            }

            this.WriteDelivery(delivery);
        }
示例#5
0
 internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
 {
     throw new InvalidOperationException();
 }
示例#6
0
        internal override void OnDeliveryStateChanged(Delivery delivery)
        {
            // some broker may not settle the message when sending dispositions
            if (!delivery.Settled)
            {
                this.Session.DisposeDelivery(false, delivery, new Accepted(), true);
            }

            if (delivery.OnOutcome != null)
            {
                Outcome outcome = delivery.State as Outcome;
            #if NETFX || NETFX40 || DOTNET
                if (delivery.State != null && delivery.State is Amqp.Transactions.TransactionalState)
                {
                    outcome = ((Amqp.Transactions.TransactionalState)delivery.State).Outcome;
                }
            #endif
                delivery.OnOutcome(delivery.Message, outcome, delivery.UserToken);
            }
        }
示例#7
0
 internal abstract void OnDeliveryStateChanged(Delivery delivery);
示例#8
0
        void WriteDelivery(Delivery delivery)
        {
            // Must be called under lock. Delivery must be on list already
            while (this.outgoingWindow > 0 && delivery != null)
            {
                --this.outgoingWindow;
                Transfer transfer = new Transfer() { Handle = delivery.Handle };

                bool first = delivery.BytesTransfered == 0;
                if (first)
                {
                    // initialize properties for first transfer
                    delivery.DeliveryId = this.outgoingDeliveryId++;
                    transfer.DeliveryTag = delivery.Tag;
                    transfer.DeliveryId = delivery.DeliveryId;
                    transfer.State = delivery.State;
                    transfer.MessageFormat = 0;
                    transfer.Settled = delivery.Settled;
                    transfer.Batchable = true;
                }

                int len = this.connection.SendCommand(this.channel, transfer, first,
                    delivery.Buffer, delivery.ReservedBufferSize);
                delivery.BytesTransfered += len;

                if (delivery.Buffer.Length == 0)
                {
                    delivery.Buffer.ReleaseReference();
                    Delivery next = (Delivery)delivery.Next;
                    if (delivery.Settled)
                    {
                        this.outgoingList.Remove(delivery);
                    }

                    delivery = next;
                }
            }
        }
示例#9
0
 internal override void OnDeliveryStateChanged(Delivery delivery)
 {
 }
示例#10
0
        internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
        {
            if (delivery == null)
            {
                delivery = this.deliveryCurrent;
                AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
            }
            else
            {
                buffer.AddReference();
                delivery.Buffer = buffer;
                lock (this.ThisLock)
                {
                    this.OnDelivery(transfer.DeliveryId);
                }
            }

            if (!transfer.More)
            {
                this.deliveryCurrent = null;
                delivery.Message = Message.Decode(delivery.Buffer);

                Waiter waiter;
                MessageCallback callback = this.onMessage;
                lock (this.ThisLock)
                {
                    waiter = (Waiter)this.waiterList.First;
                    if (waiter != null)
                    {
                        this.waiterList.Remove(waiter);
                    }
                    else if (callback == null)
                    {
                        this.receivedMessages.Add(new MessageNode() { Message = delivery.Message });
                        return;
                    }
                }

                while (waiter != null)
                {
                    if (waiter.Signal(delivery.Message))
                    {
                        this.OnDeliverMessage();
                        return;
                    }

                    lock (this.ThisLock)
                    {
                        waiter = (Waiter)this.waiterList.First;
                        if (waiter != null)
                        {
                            this.waiterList.Remove(waiter);
                        }
                        else if (callback == null)
                        {
                            this.receivedMessages.Add(new MessageNode() { Message = delivery.Message });
                            return;
                        }
                    }
                }

                Fx.Assert(waiter == null, "waiter must be null now");
                Fx.Assert(callback != null, "callback must not be null now");
                callback(this, delivery.Message);
                this.OnDeliverMessage();
            }
            else
            {
                this.deliveryCurrent = delivery;
            }
        }
示例#11
0
        internal void Send(Message message, DeliveryState deliveryState, OutcomeCallback callback, object state)
        {
            var buffer = message.Encode();
            if (buffer.Length < 1)
            {
                throw new ArgumentException("Cannot send an empty message.");
            }

            Delivery delivery = new Delivery()
            {
                Message = message,
                Buffer = buffer,
                State = deliveryState,
                Link = this,
                OnOutcome = callback,
                UserToken = state,
                Settled = this.settleMode == SenderSettleMode.Settled || callback == null
            };

            lock (this.ThisLock)
            {
                this.ThrowIfDetaching("Send");

                if (this.credit <= 0 || this.writing)
                {
                    this.outgoingList.Add(delivery);
                    return;
                }

                delivery.Tag = GetDeliveryTag(this.deliveryCount);
                this.credit--;
                this.deliveryCount++;
                this.writing = true;
            }

            this.WriteDelivery(delivery);
        }
示例#12
0
        internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
        {
            if (!transfer.More)
            {
                Waiter waiter;
                MessageCallback callback;
                lock (this.ThisLock)
                {
                    if (delivery == null)
                    {
                        // multi-transfer delivery
                        delivery = this.deliveryCurrent;
                        this.deliveryCurrent = null;
                        Fx.Assert(delivery != null, "Must have a delivery in the queue");
                        AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
                        delivery.Message = Message.Decode(delivery.Buffer);
                        delivery.Buffer = null;
                    }
                    else
                    {
                        // single tranfer delivery
                        this.OnDelivery(transfer.DeliveryId);
                        delivery.Message = Message.Decode(buffer);
                    }

                    callback = this.onMessage;
                    waiter = (Waiter)this.waiterList.First;
                    if (waiter != null)
                    {
                        this.waiterList.Remove(waiter);
                    }

                    if (waiter == null && callback == null)
                    {
                        this.receivedMessages.Add(new MessageNode() { Message = delivery.Message });
                        return;
                    }
                }

                while (waiter != null)
                {
                    if (waiter.Signal(delivery.Message))
                    {
                        this.OnDeliverMessage();
                        return;
                    }

                    lock (this.ThisLock)
                    {
                        waiter = (Waiter)this.waiterList.First;
                        if (waiter != null)
                        {
                            this.waiterList.Remove(waiter);
                        }
                        else if (callback == null)
                        {
                            this.receivedMessages.Add(new MessageNode() { Message = delivery.Message });
                            return;
                        }
                    }
                }

                Fx.Assert(waiter == null, "waiter must be null now");
                Fx.Assert(callback != null, "callback must not be null now");
                callback(this, delivery.Message);
                this.OnDeliverMessage();
            }
            else
            {
                lock (this.ThisLock)
                {
                    if (delivery == null)
                    {
                        delivery = this.deliveryCurrent;
                        Fx.Assert(delivery != null, "Must have a current delivery");
                        AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
                    }
                    else
                    {
                        this.OnDelivery(transfer.DeliveryId);
                        delivery.Buffer = new ByteBuffer(buffer.Length * 2, true);
                        AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
                        this.deliveryCurrent = delivery;
                    }
                }
            }
        }
示例#13
0
 internal override void OnDeliveryStateChanged(Delivery delivery)
 {
 }
示例#14
0
        internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
        {
            if (delivery == null)
            {
                delivery = this.deliveryCurrent;
                AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
            }
            else
            {
                buffer.AddReference();
                delivery.Buffer = buffer;
                lock (this.ThisLock)
                {
                    this.OnDelivery(transfer.DeliveryId);
                }
            }

            if (!transfer.More)
            {
                this.deliveryCurrent = null;
                delivery.Message     = Message.Decode(delivery.Buffer);

                IHandler handler = this.Session.Connection.Handler;
                if (handler != null && handler.CanHandle(EventId.ReceiveDelivery))
                {
                    handler.Handle(Event.Create(EventId.ReceiveDelivery, this.Session.Connection, this.Session, this, context: delivery));
                }

                Waiter          waiter;
                MessageCallback callback = this.onMessage;
                lock (this.ThisLock)
                {
                    waiter = (Waiter)this.waiterList.First;
                    if (waiter != null)
                    {
                        this.waiterList.Remove(waiter);
                    }
                    else if (callback == null)
                    {
                        this.receivedMessages.Add(new MessageNode()
                        {
                            Message = delivery.Message
                        });
                        return;
                    }
                }

                while (waiter != null)
                {
                    if (waiter.Signal(delivery.Message))
                    {
                        return;
                    }

                    lock (this.ThisLock)
                    {
                        waiter = (Waiter)this.waiterList.First;
                        if (waiter != null)
                        {
                            this.waiterList.Remove(waiter);
                        }
                        else if (callback == null)
                        {
                            this.receivedMessages.Add(new MessageNode()
                            {
                                Message = delivery.Message
                            });
                            return;
                        }
                    }
                }

                Fx.Assert(waiter == null, "waiter must be null now");
                Fx.Assert(callback != null, "callback must not be null now");
                callback(this, delivery.Message);
            }
            else
            {
                this.deliveryCurrent = delivery;
            }
        }
 internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
 {
     throw new InvalidOperationException();
 }
示例#16
0
        internal void SendDelivery(Delivery delivery)
        {
            lock (this.ThisLock)
            {
                this.outgoingList.Add(delivery);

                this.WriteDelivery(delivery);
            }
        }
示例#17
0
        void OnTransfer(Transfer transfer, ByteBuffer buffer)
        {
            bool newDelivery;
            lock (this.ThisLock)
            {
                if (this.incomingWindow-- == 0)
                {
                    this.SendFlow(new Flow());
                }

                this.nextIncomingId++;
                newDelivery = transfer.HasDeliveryId && transfer.DeliveryId > this.incomingDeliveryId;
                if (newDelivery)
                {
                    this.incomingDeliveryId = transfer.DeliveryId;
                }
            }

            Link link = this.GetLink(transfer.Handle);
            Delivery delivery = null;
            if (newDelivery)
            {
                delivery = new Delivery()
                {
                    DeliveryId = transfer.DeliveryId,
                    Link = link,
                    Tag = transfer.DeliveryTag,
                    Settled = transfer.Settled,
                    State = transfer.State
                };

                if (!delivery.Settled)
                {
                    lock (this.ThisLock)
                    {
                        this.incomingList.Add(delivery);
                    }
                }
            }

            link.OnTransfer(delivery, transfer, buffer);
        }
示例#18
0
 internal abstract void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer);
示例#19
0
 internal abstract void OnDeliveryStateChanged(Delivery delivery);
示例#20
0
 internal abstract void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer);