internal protected bool TryAssociateLink()

in src/AmqpLinkTerminus.cs [169:236]


        internal protected bool TryAssociateLink(AmqpLink newLink, out AmqpLink stolenLink)
        {
            stolenLink = null;
            lock (this.thisLock)
            {
                if (disposed)
                {
                    return false;
                }

                if (this.link != null)
                {
                    if (newLink.AllowLinkStealing(this.LinkSettings))
                    {
                        stolenLink = this.link;
                        // Before disassociating the link, save current Unsettledmap of the link.
                        // On local side, when abort is called, Close handlers are invoked and terminus state
                        // is saved. Remote side, does not see abort and hence is not closed, so the remote side
                        // will have the link in Open state. Before allowing the stealing of link, save the
                        // current state of the link.
                        if (this.Link.State != AmqpObjectState.End)
                        {
                            this.TerminusStore.SaveDeliveriesAsync(this, this.link.UnsettledMap).GetAwaiter().GetResult();
                        }
                        this.DisassociateLink();
                    }
                    else
                    {
                        return false;
                    }
                }

                this.link = newLink;
                newLink.Terminus = this;

                newLink.Closed += this.OnAssociatedLinkClose;
                AmqpSymbol expiryPolicy = newLink.Settings.GetExpiryPolicy();
                if (expiryPolicy.Equals(TerminusExpiryPolicy.LinkDetach))
                {
                    newLink.Closed += this.OnSuspendLinkTerminus;
                }
                else if (expiryPolicy.Equals(TerminusExpiryPolicy.SessionEnd))
                {
                    newLink.Session.Closed += this.OnSuspendLinkTerminus;
                }
                else if (expiryPolicy.Equals(TerminusExpiryPolicy.ConnectionClose))
                {
                    newLink.Session.Connection.Closed += this.OnSuspendLinkTerminus;
                }
            }

            IDictionary<ArraySegment<byte>, Delivery> localUnsettledDeliveries = this.TerminusStore.RetrieveDeliveriesAsync(this).Result;
            if (localUnsettledDeliveries != null)
            {
                if (newLink.Settings.Unsettled == null)
                {
                    newLink.Settings.Unsettled = new AmqpMap(MapKeyByteArrayComparer.Instance);
                }

                foreach (var kvp in localUnsettledDeliveries)
                {
                    newLink.Settings.Unsettled.Add(new MapKey(kvp.Key), kvp.Value.State);
                }
            }

            stolenLink?.OnLinkStolen();
            return true;
        }