Ejemplo n.º 1
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(this, delivery.Message, new Accepted(), delivery.UserToken);
                    }
                }
                catch
                {
                    lock (this.ThisLock)
                    {
                        this.writing = false;
                    }

                    throw;
                }

                bool shouldClose = false;
                lock (this.ThisLock)
                {
                    delivery = (Delivery)this.outgoingList.First;
                    if (delivery == null || this.credit == 0)
                    {
                        shouldClose  = this.CloseCalled;
                        delivery     = null;
                        this.writing = false;
                    }
                    else if (this.credit > 0)
                    {
                        this.outgoingList.Remove(delivery);
                        delivery.Tag = Delivery.GetDeliveryTag(this.deliveryCount);
                        this.credit--;
                        this.deliveryCount++;
                    }
                }

                if (shouldClose)
                {
                    Error error = this.Error;
                    this.OnAbort(error);
                    if (base.OnClose(error))
                    {
                        this.NotifyClosed(error);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        void SendInternal(Message message, DeliveryState deliveryState, OutcomeCallback callback, object state, bool sync)
        {
            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,
                Batchable = !sync
            };

            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);
        }
        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;
                    }
                }
            }
        }
        internal override void OnFlow(Flow flow)
        {
            Delivery delivery = null;

            lock (this.ThisLock)
            {
                this.credit = (flow.DeliveryCount + flow.LinkCredit) - this.deliveryCount;
                if (this.writing || this.credit <= 0 || this.outgoingList.First == null)
                {
                    return;
                }

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

            this.WriteDelivery(delivery);
        }