// Must call in a lock(this.ThisLock).
        MessageAttemptInfo AddToWindow(Message message, bool isLast, object state)
        {
            MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);
            Int64 sequenceNumber;

            sequenceNumber = this.windowStart + this.window.Count;
            WsrmUtilities.AddSequenceHeader(this.reliableMessagingVersion, message, this.id, sequenceNumber, isLast);

            if (this.requestAcks && (this.window.Count == this.windowSize - 1 || this.quotaRemaining == 1)) // can't add any more
            {
                message.Properties.AllowOutputBatching = false;
                WsrmUtilities.AddAckRequestedHeader(this.reliableMessagingVersion, message, this.id);
            }

            if (this.window.Count == 0)
            {
                this.retryTimer.Set(this.Timeout);
            }

            this.window.Add(message, Now, state);
            this.quotaRemaining--;
            if (isLast)
            {
                this.last = sequenceNumber;
            }

            int index = (int)(sequenceNumber - this.windowStart);

            attemptInfo = new MessageAttemptInfo(this.window.GetMessage(index), sequenceNumber, 0, state);

            return(attemptInfo);
        }
        private bool InternalAdd(Message message, bool isLast, TimeSpan timeout, object state, out MessageAttemptInfo attemptInfo)
        {
            WaitQueueAdder adder;

            attemptInfo = new MessageAttemptInfo();
            lock (this.ThisLock)
            {
                if (isLast && (this.last != 0L))
                {
                    throw Fx.AssertAndThrow("Can't add more than one last message.");
                }
                if (!this.IsAddValid())
                {
                    return(false);
                }
                this.ThrowIfRollover();
                if (this.CanAdd())
                {
                    attemptInfo = this.AddToWindow(message, isLast, state);
                    return(true);
                }
                adder = new WaitQueueAdder(this, message, isLast, state);
                this.waitQueue.Enqueue(adder);
            }
            attemptInfo = adder.Wait(timeout);
            return(true);
        }
        private IAsyncResult InternalBeginAdd(Message message, bool isLast, TimeSpan timeout, object state, AsyncCallback callback, object asyncState)
        {
            bool flag;
            MessageAttemptInfo parameter = new MessageAttemptInfo();

            lock (this.ThisLock)
            {
                if (isLast && (this.last != 0L))
                {
                    throw Fx.AssertAndThrow("Can't add more than one last message.");
                }
                flag = this.IsAddValid();
                if (flag)
                {
                    this.ThrowIfRollover();
                    if (!this.CanAdd())
                    {
                        AsyncQueueAdder item = new AsyncQueueAdder(message, isLast, timeout, state, this, callback, asyncState);
                        this.waitQueue.Enqueue(item);
                        return(item);
                    }
                    parameter = this.AddToWindow(message, isLast, state);
                }
            }
            return(new CompletedAsyncResult <bool, MessageAttemptInfo>(flag, parameter, callback, asyncState));
        }
        public MessageAttemptInfo EndAddLast(IAsyncResult result)
        {
            MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);

            InternalEndAdd(result, out attemptInfo);
            return(attemptInfo);
        }
        public MessageAttemptInfo EndAddLast(IAsyncResult result)
        {
            MessageAttemptInfo attemptInfo = new MessageAttemptInfo();

            this.InternalEndAdd(result, out attemptInfo);
            return(attemptInfo);
        }
        // Must call in a lock(this.ThisLock).
        private MessageAttemptInfo AddToWindow(Message message, bool isLast, object state)
        {
            MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);
            long sequenceNumber;

            sequenceNumber = _windowStart + _window.Count;
            WsrmUtilities.AddSequenceHeader(_reliableMessagingVersion, message, _id, sequenceNumber, isLast);

            if (_requestAcks && (_window.Count == _windowSize - 1 || QuotaRemaining == 1)) // can't add any more
            {
                message.Properties.AllowOutputBatching = false;
                WsrmUtilities.AddAckRequestedHeader(_reliableMessagingVersion, message, _id);
            }

            if (_window.Count == 0)
            {
                _retryTimer.Set(Timeout);
            }

            _window.Add(message, Now, state);
            QuotaRemaining--;
            if (isLast)
            {
                Last = sequenceNumber;
            }

            int index = (int)(sequenceNumber - _windowStart);

            attemptInfo = new MessageAttemptInfo(_window.GetMessage(index), sequenceNumber, 0, state);

            return(attemptInfo);
        }
        private IAsyncResult OnConnectionBeginSend(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException, AsyncCallback callback, object state)
        {
            if (attemptInfo.RetryCount > this.settings.MaxRetryCount)
            {
                this.session.OnLocalFault(new CommunicationException(System.ServiceModel.SR.GetString("MaximumRetryCountExceeded"), this.maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null);
                return(new CompletedAsyncResult(callback, state));
            }
            this.session.OnLocalActivity();
            this.AddAcknowledgementHeader(attemptInfo.Message, false);
            ReliableBinderRequestAsyncResult result = new ReliableBinderRequestAsyncResult(callback, state)
            {
                Binder             = this.binder,
                MessageAttemptInfo = attemptInfo,
                MaskingMode        = maskUnhandledException ? MaskingMode.Unhandled : MaskingMode.None
            };

            if (attemptInfo.RetryCount < this.settings.MaxRetryCount)
            {
                result.MaskingMode         |= MaskingMode.Handled;
                result.SaveHandledException = false;
            }
            else
            {
                result.SaveHandledException = true;
            }
            result.Begin(timeout);
            return(result);
        }
        void CompleteSendRetries(IAsyncResult result)
        {
            while (true)
            {
                this.endSendHandler(result);
                this.sendGuard.Exit();
                this.strategy.DequeuePending();

                if (this.sendGuard.Enter())
                {
                    MessageAttemptInfo attemptInfo = this.strategy.GetMessageInfoForRetry(true);

                    if (attemptInfo.Message == null)
                    {
                        break;
                    }
                    else
                    {
                        result = this.beginSendHandler(attemptInfo, this.sendTimeout, true, onSendRetriesComplete, this);
                        if (!result.CompletedSynchronously)
                        {
                            return;
                        }
                    }
                }
                else
                {
                    return;
                }
            }

            // We are here if there are no more messages to retry.
            this.sendGuard.Exit();
            this.OnTransferComplete();
        }
        private async Task <(MessageAttemptInfo attemptInfo, bool success)> InternalAddAsync(Message message, bool isLast, TimeSpan timeout, object state)
        {
            MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);

            AsyncWaitQueueAdder adder;

            lock (ThisLock)
            {
                if (isLast && Last != 0)
                {
                    throw Fx.AssertAndThrow("Can't add more than one last message.");
                }

                if (!IsAddValid())
                {
                    return(attemptInfo, false);
                }

                ThrowIfRollover();

                if (CanAdd())
                {
                    attemptInfo = AddToWindow(message, isLast, state);
                    return(attemptInfo, true);
                }

                adder = new AsyncWaitQueueAdder(this, message, isLast, state);
                _waitQueue.Enqueue(adder);
            }

            attemptInfo = await adder.WaitAsync(timeout);

            return(attemptInfo, true);
        }
        private void SendRetries()
        {
            IAsyncResult result = null;

            if (this.sendGuard.Enter())
            {
                MessageAttemptInfo messageInfoForRetry = this.strategy.GetMessageInfoForRetry(false);
                if (messageInfoForRetry.Message != null)
                {
                    result = this.beginSendHandler(messageInfoForRetry, this.sendTimeout, true, onSendRetriesComplete, this);
                }
                if (result != null)
                {
                    if (result.CompletedSynchronously)
                    {
                        this.CompleteSendRetries(result);
                    }
                }
                else
                {
                    this.sendGuard.Exit();
                    this.OnTransferComplete();
                }
            }
        }
        IAsyncResult InternalBeginAdd(Message message, bool isLast, TimeSpan timeout, object state, AsyncCallback callback, object asyncState)
        {
            MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);
            bool isAddValid;

            lock (this.ThisLock)
            {
                if (isLast && this.last != 0)
                {
                    throw Fx.AssertAndThrow("Can't add more than one last message.");
                }

                isAddValid = this.IsAddValid();

                if (isAddValid)
                {
                    ThrowIfRollover();

                    if (CanAdd())
                    {
                        attemptInfo = AddToWindow(message, isLast, state);
                    }
                    else
                    {
                        AsyncQueueAdder adder = new AsyncQueueAdder(message, isLast, timeout, state, this, callback, asyncState);
                        this.waitQueue.Enqueue(adder);

                        return(adder);
                    }
                }
            }

            return(new CompletedAsyncResult <bool, MessageAttemptInfo>(isAddValid, attemptInfo, callback, asyncState));
        }
 public AsyncQueueAdder(Message message, bool isLast, TimeSpan timeout, object state, TransmissionStrategy strategy, AsyncCallback callback, object asyncState) : base(timeout, true, callback, asyncState)
 {
     this.attemptInfo = new MessageAttemptInfo();
     this.attemptInfo = new MessageAttemptInfo(message, 0L, 0, state);
     this.isLast      = isLast;
     this.strategy    = strategy;
     base.Begin();
 }
 private bool InternalEndAdd(IAsyncResult result, out MessageAttemptInfo attemptInfo)
 {
     if (result is CompletedAsyncResult <bool, MessageAttemptInfo> )
     {
         return(CompletedAsyncResult <bool, MessageAttemptInfo> .End(result, out attemptInfo));
     }
     attemptInfo = AsyncQueueAdder.End((AsyncQueueAdder)result);
     return(true);
 }
Example #14
0
        private async Task OnConnectionSendAsync(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException)
        {
            using (attemptInfo.Message)
            {
                if (attemptInfo.RetryCount > settings.MaxRetryCount)
                {
                    if (WcfEventSource.Instance.MaxRetryCyclesExceededIsEnabled())
                    {
                        WcfEventSource.Instance.MaxRetryCyclesExceeded(SR.MaximumRetryCountExceeded);
                    }
                    session.OnLocalFault(new CommunicationException(SR.MaximumRetryCountExceeded, maxRetryCountException),
                                         SequenceTerminatedFault.CreateMaxRetryCountExceededFault(session.OutputID), null);
                    return;
                }

                AddAcknowledgementHeader(attemptInfo.Message, false);
                session.OnLocalActivity();

                Message     reply       = null;
                MaskingMode maskingMode = maskUnhandledException ? MaskingMode.Unhandled : MaskingMode.None;

                if (attemptInfo.RetryCount < settings.MaxRetryCount)
                {
                    maskingMode |= MaskingMode.Handled;
                    reply        = await binder.RequestAsync(attemptInfo.Message, timeout, maskingMode);
                }
                else
                {
                    try
                    {
                        reply = await binder.RequestAsync(attemptInfo.Message, timeout, maskingMode);
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e))
                        {
                            throw;
                        }

                        if (binder.IsHandleable(e))
                        {
                            maxRetryCountException = e;
                        }
                        else
                        {
                            throw;
                        }
                    }
                }

                if (reply != null)
                {
                    ProcessReply(reply, (IReliableRequest)attemptInfo.State, attemptInfo.GetSequenceNumber());
                }
            }
        }
        void OnConnectionSend(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException)
        {
            using (attemptInfo.Message)
            {
                if (attemptInfo.RetryCount > this.settings.MaxRetryCount)
                {
                    if (TD.MaxRetryCyclesExceededIsEnabled())
                    {
                        TD.MaxRetryCyclesExceeded(SR.GetString(SR.MaximumRetryCountExceeded));
                    }
                    this.session.OnLocalFault(new CommunicationException(SR.GetString(SR.MaximumRetryCountExceeded), this.maxRetryCountException),
                                              SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null);
                    return;
                }

                this.AddAcknowledgementHeader(attemptInfo.Message, false);
                this.session.OnLocalActivity();

                Message     reply       = null;
                MaskingMode maskingMode = maskUnhandledException ? MaskingMode.Unhandled : MaskingMode.None;

                if (attemptInfo.RetryCount < this.settings.MaxRetryCount)
                {
                    maskingMode |= MaskingMode.Handled;
                    reply        = this.binder.Request(attemptInfo.Message, timeout, maskingMode);
                }
                else
                {
                    try
                    {
                        reply = this.binder.Request(attemptInfo.Message, timeout, maskingMode);
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e))
                        {
                            throw;
                        }

                        if (this.binder.IsHandleable(e))
                        {
                            this.maxRetryCountException = e;
                        }
                        else
                        {
                            throw;
                        }
                    }
                }

                if (reply != null)
                {
                    ProcessReply(reply, (IReliableRequest)attemptInfo.State, attemptInfo.GetSequenceNumber());
                }
            }
        }
 private IAsyncResult OnConnectionBeginSendHandler(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException, AsyncCallback callback, object state)
 {
     if (attemptInfo.RetryCount > this.settings.MaxRetryCount)
     {
         this.session.OnLocalFault(new CommunicationException(System.ServiceModel.SR.GetString("MaximumRetryCountExceeded"), this.maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null);
         return(new CompletedAsyncResult(callback, state));
     }
     this.session.OnLocalActivity();
     return(this.OnConnectionBeginSend(attemptInfo, timeout, maskUnhandledException, callback, state));
 }
 public AsyncQueueAdder(Message message, bool isLast, TimeSpan timeout, object state, TransmissionStrategy strategy, AsyncCallback callback, object asyncState)
     : base(timeout, true, callback, asyncState)
 {
     // MessageAttemptInfo(Message message, Int64 sequenceNumber, int retryCount, object state)
     // this.attemptInfo is just a state bag, thus sequenceNumber can be 0 and should never be read.
     this.attemptInfo = new MessageAttemptInfo(message, 0, 0, state);
     this.isLast      = isLast;
     this.strategy    = strategy;
     base.Begin();
 }
        public MessageAttemptInfo AddLast(Message message, TimeSpan timeout, object state)
        {
            if (this.reliableMessagingVersion != ReliableMessagingVersion.WSReliableMessagingFebruary2005)
            {
                throw Fx.AssertAndThrow("Last message supported only in February 2005.");
            }
            MessageAttemptInfo attemptInfo = new MessageAttemptInfo();

            this.InternalAdd(message, true, timeout, state, out attemptInfo);
            return(attemptInfo);
        }
 private void OnRetryTimeoutElapsed(MessageAttemptInfo attemptInfo)
 {
     if (this.sendGuard.Enter())
     {
         IAsyncResult result = this.beginSendHandler(attemptInfo, this.sendTimeout, true, onSendRetryComplete, this);
         if (result.CompletedSynchronously)
         {
             this.CompleteSendRetry(result);
         }
     }
 }
        public void OnRetryElapsed(object state)
        {
            try
            {
                MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);

                lock (this.ThisLock)
                {
                    if (this.closed)
                    {
                        return;
                    }

                    if (this.window.Count == 0)
                    {
                        return;
                    }

                    this.window.RecordRetry(0, Now);
                    this.congestionControlModeAcks = 0;
                    this.slowStartThreshold        = Math.Max(1, this.windowSize >> 1);
                    this.lossWindowSize            = this.windowSize;
                    this.windowSize = 1;
                    this.timeout  <<= 1;
                    this.startup    = false;

                    attemptInfo = new MessageAttemptInfo(this.window.GetMessage(0), this.windowStart, this.window.GetRetryCount(0), this.window.GetState(0));
                }

                retryTimeoutElapsedHandler(attemptInfo);

                lock (this.ThisLock)
                {
                    if (!this.closed && (this.window.Count > 0))
                    {
                        this.retryTimer.Set(this.Timeout);
                    }
                }
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                this.onException(e);
            }
        }
 private void OnConnectionSendHandler(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException)
 {
     using (attemptInfo.Message)
     {
         if (attemptInfo.RetryCount > this.settings.MaxRetryCount)
         {
             this.session.OnLocalFault(new CommunicationException(System.ServiceModel.SR.GetString("MaximumRetryCountExceeded"), this.maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null);
         }
         else
         {
             this.session.OnLocalActivity();
             this.OnConnectionSend(attemptInfo.Message, timeout, attemptInfo.RetryCount == this.settings.MaxRetryCount, maskUnhandledException);
         }
     }
 }
        // Although this method does no async work itself, it does call an async method which continues
        // in the background. Because of this we need to use the async varient of IOThreadTimer to use
        // the IOThreadScheduler for Task continuations.
        public Task OnRetryElapsed(object state)
        {
            try
            {
                MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);

                lock (ThisLock)
                {
                    if (_closed || _window.Count == 0)
                    {
                        return(Task.CompletedTask);
                    }

                    _window.RecordRetry(0, Now);
                    _congestionControlModeAcks = 0;
                    _slowStartThreshold        = Math.Max(1, _windowSize >> 1);
                    _lossWindowSize            = _windowSize;
                    _windowSize = 1;
                    _timeout  <<= 1;
                    _startup    = false;

                    attemptInfo = new MessageAttemptInfo(_window.GetMessage(0), _windowStart, _window.GetRetryCount(0), _window.GetState(0));
                }

                // We specifically do not want to wait for the retry to complete before setting the timer for the next retry
                // The retry timeout elapsed handler continues asynchronously in the background
                _ = _retryTimeoutElapsedHandler(attemptInfo);

                lock (ThisLock)
                {
                    if (!_closed && (_window.Count > 0))
                    {
                        _retryTimer.Set(Timeout);
                    }
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                _onException(e);
            }

            return(Task.CompletedTask);
        }
 protected override IAsyncResult OnConnectionBeginSend(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException, AsyncCallback callback, object state)
 {
     ReliableBinderSendAsyncResult result = new ReliableBinderSendAsyncResult(callback, state) {
         Binder = base.Binder,
         MessageAttemptInfo = attemptInfo,
         MaskingMode = maskUnhandledException ? MaskingMode.Unhandled : MaskingMode.None
     };
     if (attemptInfo.RetryCount < base.Settings.MaxRetryCount)
     {
         result.MaskingMode |= MaskingMode.Handled;
         result.SaveHandledException = false;
     }
     else
     {
         result.SaveHandledException = true;
     }
     result.Begin(timeout);
     return result;
 }
 private void CompleteSendRetries(IAsyncResult result)
 {
     do
     {
         this.endSendHandler(result);
         this.sendGuard.Exit();
         this.strategy.DequeuePending();
         if (!this.sendGuard.Enter())
         {
             break;
         }
         MessageAttemptInfo messageInfoForRetry = this.strategy.GetMessageInfoForRetry(true);
         if (messageInfoForRetry.Message == null)
         {
             this.sendGuard.Exit();
             this.OnTransferComplete();
             return;
         }
         result = this.beginSendHandler(messageInfoForRetry, this.sendTimeout, true, onSendRetriesComplete, this);
     }while (result.CompletedSynchronously);
 }
 private async Task OnConnectionSendAsyncHandler(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException)
 {
     using (attemptInfo.Message)
     {
         if (attemptInfo.RetryCount > Settings.MaxRetryCount)
         {
             if (WcfEventSource.Instance.MaxRetryCyclesExceededIsEnabled())
             {
                 WcfEventSource.Instance.MaxRetryCyclesExceeded(SR.MaximumRetryCountExceeded);
             }
             _session.OnLocalFault(new CommunicationException(SR.MaximumRetryCountExceeded, _maxRetryCountException),
                                   SequenceTerminatedFault.CreateMaxRetryCountExceededFault(_session.OutputID), null);
         }
         else
         {
             _session.OnLocalActivity();
             await OnConnectionSendAsync(attemptInfo.Message, timeout,
                                         (attemptInfo.RetryCount == Settings.MaxRetryCount), maskUnhandledException);
         }
     }
 }
 void OnConnectionSendHandler(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException)
 {
     using (attemptInfo.Message)
     {
         if (attemptInfo.RetryCount > this.settings.MaxRetryCount)
         {
             if (TD.MaxRetryCyclesExceededIsEnabled())
             {
                 TD.MaxRetryCyclesExceeded(SR.GetString(SR.MaximumRetryCountExceeded));
             }
             this.session.OnLocalFault(new CommunicationException(SR.GetString(SR.MaximumRetryCountExceeded), this.maxRetryCountException),
                                       SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null);
         }
         else
         {
             this.session.OnLocalActivity();
             OnConnectionSend(attemptInfo.Message, timeout,
                              (attemptInfo.RetryCount == this.settings.MaxRetryCount), maskUnhandledException);
         }
     }
 }
        protected override IAsyncResult OnConnectionBeginSend(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException, AsyncCallback callback, object state)
        {
            ReliableBinderSendAsyncResult result = new ReliableBinderSendAsyncResult(callback, state)
            {
                Binder             = base.Binder,
                MessageAttemptInfo = attemptInfo,
                MaskingMode        = maskUnhandledException ? MaskingMode.Unhandled : MaskingMode.None
            };

            if (attemptInfo.RetryCount < base.Settings.MaxRetryCount)
            {
                result.MaskingMode         |= MaskingMode.Handled;
                result.SaveHandledException = false;
            }
            else
            {
                result.SaveHandledException = true;
            }
            result.Begin(timeout);
            return(result);
        }
 private bool InternalAdd(Message message, bool isLast, TimeSpan timeout, object state, out MessageAttemptInfo attemptInfo)
 {
     WaitQueueAdder adder;
     attemptInfo = new MessageAttemptInfo();
     lock (this.ThisLock)
     {
         if (isLast && (this.last != 0L))
         {
             throw Fx.AssertAndThrow("Can't add more than one last message.");
         }
         if (!this.IsAddValid())
         {
             return false;
         }
         this.ThrowIfRollover();
         if (this.CanAdd())
         {
             attemptInfo = this.AddToWindow(message, isLast, state);
             return true;
         }
         adder = new WaitQueueAdder(this, message, isLast, state);
         this.waitQueue.Enqueue(adder);
     }
     attemptInfo = adder.Wait(timeout);
     return true;
 }
 public MessageAttemptInfo EndAddLast(IAsyncResult result)
 {
     MessageAttemptInfo attemptInfo = new MessageAttemptInfo();
     this.InternalEndAdd(result, out attemptInfo);
     return attemptInfo;
 }
 public bool EndAdd(IAsyncResult result, out MessageAttemptInfo attemptInfo)
 {
     return this.InternalEndAdd(result, out attemptInfo);
 }
 public AsyncQueueAdder(Message message, bool isLast, TimeSpan timeout, object state, TransmissionStrategy strategy, AsyncCallback callback, object asyncState)
     : base(timeout, true, callback, asyncState)
 {
     // MessageAttemptInfo(Message message, Int64 sequenceNumber, int retryCount, object state)
     // this.attemptInfo is just a state bag, thus sequenceNumber can be 0 and should never be read.
     this.attemptInfo = new MessageAttemptInfo(message, 0, 0, state);
     this.isLast = isLast;
     this.strategy = strategy;
     base.Begin();
 }
 public void Complete0()
 {
     _attemptInfo = _strategy.AddToWindow(_attemptInfo.Message, _isLast, _attemptInfo.State);
     _tcs.TrySetResult(null);
 }
 public void Complete0()
 {
     this.attemptInfo = this.strategy.AddToWindow(this.attemptInfo.Message, this.isLast, this.attemptInfo.State);
     this.completeEvent.Set();
 }
 public bool Add(Message message, TimeSpan timeout, object state, out MessageAttemptInfo attemptInfo)
 {
     return this.InternalAdd(message, false, timeout, state, out attemptInfo);
 }
 public void OnRetryElapsed(object state)
 {
     try
     {
         MessageAttemptInfo attemptInfo = new MessageAttemptInfo();
         lock (this.ThisLock)
         {
             if (this.closed || (this.window.Count == 0))
             {
                 return;
             }
             this.window.RecordRetry(0, Now);
             this.congestionControlModeAcks = 0;
             this.slowStartThreshold = Math.Max(1, this.windowSize >> 1);
             this.lossWindowSize = this.windowSize;
             this.windowSize = 1;
             this.timeout = this.timeout << 1;
             this.startup = false;
             attemptInfo = new MessageAttemptInfo(this.window.GetMessage(0), this.windowStart, this.window.GetRetryCount(0), this.window.GetState(0));
         }
         this.retryTimeoutElapsedHandler(attemptInfo);
         lock (this.ThisLock)
         {
             if (!this.closed && (this.window.Count > 0))
             {
                 this.retryTimer.Set(this.Timeout);
             }
         }
     }
     catch (Exception exception)
     {
         if (Fx.IsFatal(exception))
         {
             throw;
         }
         this.onException(exception);
     }
 }
 private IAsyncResult InternalBeginAdd(Message message, bool isLast, TimeSpan timeout, object state, AsyncCallback callback, object asyncState)
 {
     bool flag;
     MessageAttemptInfo parameter = new MessageAttemptInfo();
     lock (this.ThisLock)
     {
         if (isLast && (this.last != 0L))
         {
             throw Fx.AssertAndThrow("Can't add more than one last message.");
         }
         flag = this.IsAddValid();
         if (flag)
         {
             this.ThrowIfRollover();
             if (!this.CanAdd())
             {
                 AsyncQueueAdder item = new AsyncQueueAdder(message, isLast, timeout, state, this, callback, asyncState);
                 this.waitQueue.Enqueue(item);
                 return item;
             }
             parameter = this.AddToWindow(message, isLast, state);
         }
     }
     return new CompletedAsyncResult<bool, MessageAttemptInfo>(flag, parameter, callback, asyncState);
 }
 protected abstract IAsyncResult OnConnectionBeginSend(MessageAttemptInfo attemptInfo, TimeSpan timeout,
                                                       bool maskUnhandledException, AsyncCallback callback, object state);
 private bool CompleteAdd(IAsyncResult result)
 {
     MessageAttemptInfo attemptInfo = new MessageAttemptInfo();
     this.validAdd = true;
     try
     {
         if (this.isLast)
         {
             attemptInfo = this.connection.strategy.EndAddLast(result);
         }
         else if (!this.connection.strategy.EndAdd(result, out attemptInfo))
         {
             this.validAdd = false;
             return true;
         }
     }
     catch (TimeoutException)
     {
         if (this.isLast)
         {
             this.connection.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.connection.id, System.ServiceModel.SR.GetString("SequenceTerminatedAddLastToWindowTimedOut"), null));
         }
         throw;
     }
     catch (Exception exception)
     {
         if (!Fx.IsFatal(exception))
         {
             this.connection.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.connection.id, System.ServiceModel.SR.GetString("SequenceTerminatedUnknownAddToWindowError"), null));
         }
         throw;
     }
     if (this.connection.sendGuard.Enter())
     {
         bool flag = true;
         try
         {
             result = this.connection.beginSendHandler(attemptInfo, this.timeoutHelper.RemainingTime(), false, sendCompleteStatic, this);
             flag = false;
         }
         catch (QuotaExceededException)
         {
             this.connection.RaiseFault(null, SequenceTerminatedFault.CreateQuotaExceededFault(this.connection.id));
             throw;
         }
         finally
         {
             if (flag)
             {
                 this.connection.sendGuard.Exit();
             }
         }
     }
     else
     {
         return true;
     }
     if (result.CompletedSynchronously)
     {
         this.CompleteSend(result);
         return true;
     }
     return false;
 }
        public void OnRetryElapsed(object state)
        {
            try
            {
                MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);

                lock (this.ThisLock)
                {
                    if (this.closed)
                        return;

                    if (this.window.Count == 0)
                        return;

                    this.window.RecordRetry(0, Now);
                    this.congestionControlModeAcks = 0;
                    this.slowStartThreshold = Math.Max(1, this.windowSize >> 1);
                    this.lossWindowSize = this.windowSize;
                    this.windowSize = 1;
                    this.timeout <<= 1;
                    this.startup = false;

                    attemptInfo = new MessageAttemptInfo(this.window.GetMessage(0), this.windowStart, this.window.GetRetryCount(0), this.window.GetState(0));
                }

                retryTimeoutElapsedHandler(attemptInfo);

                lock (this.ThisLock)
                {
                    if (!this.closed && (this.window.Count > 0))
                    {
                        this.retryTimer.Set(this.Timeout);
                    }
                }
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                    throw;

                this.onException(e);
            }
        }
 private bool InternalEndAdd(IAsyncResult result, out MessageAttemptInfo attemptInfo)
 {
     if (result is CompletedAsyncResult<bool, MessageAttemptInfo>)
     {
         return CompletedAsyncResult<bool, MessageAttemptInfo>.End(result, out attemptInfo);
     }
     attemptInfo = AsyncQueueAdder.End((AsyncQueueAdder) result);
     return true;
 }
 public void Complete0()
 {
     this.attemptInfo = strategy.AddToWindow(this.attemptInfo.Message, this.isLast, this.attemptInfo.State);
 }
 public AsyncQueueAdder(Message message, bool isLast, TimeSpan timeout, object state, TransmissionStrategy strategy, AsyncCallback callback, object asyncState) : base(timeout, true, callback, asyncState)
 {
     this.attemptInfo = new MessageAttemptInfo();
     this.attemptInfo = new MessageAttemptInfo(message, 0L, 0, state);
     this.isLast = isLast;
     this.strategy = strategy;
     base.Begin();
 }
 public AsyncWaitQueueAdder(TransmissionStrategy strategy, Message message, bool isLast, object state)
 {
     _strategy    = strategy;
     _isLast      = isLast;
     _attemptInfo = new MessageAttemptInfo(message, 0, 0, state);
 }
 public MessageAttemptInfo AddLast(Message message, TimeSpan timeout, object state)
 {
     if (this.reliableMessagingVersion != ReliableMessagingVersion.WSReliableMessagingFebruary2005)
     {
         throw Fx.AssertAndThrow("Last message supported only in February 2005.");
     }
     MessageAttemptInfo attemptInfo = new MessageAttemptInfo();
     this.InternalAdd(message, true, timeout, state, out attemptInfo);
     return attemptInfo;
 }
 private MessageAttemptInfo AddToWindow(Message message, bool isLast, object state)
 {
     MessageAttemptInfo info = new MessageAttemptInfo();
     long sequenceNumber = this.windowStart + this.window.Count;
     WsrmUtilities.AddSequenceHeader(this.reliableMessagingVersion, message, this.id, sequenceNumber, isLast);
     if (this.requestAcks && ((this.window.Count == (this.windowSize - 1)) || (this.quotaRemaining == 1)))
     {
         message.Properties.AllowOutputBatching = false;
         WsrmUtilities.AddAckRequestedHeader(this.reliableMessagingVersion, message, this.id);
     }
     if (this.window.Count == 0)
     {
         this.retryTimer.Set(this.Timeout);
     }
     this.window.Add(message, Now, state);
     this.quotaRemaining--;
     if (isLast)
     {
         this.last = sequenceNumber;
     }
     int index = (int) (sequenceNumber - this.windowStart);
     return new MessageAttemptInfo(this.window.GetMessage(index), sequenceNumber, 0, state);
 }
 public WaitQueueAdder(TransmissionStrategy strategy, Message message, bool isLast, object state)
 {
     this.strategy = strategy;
     this.isLast = isLast;
     this.attemptInfo = new MessageAttemptInfo(message, 0L, 0, state);
 }
 public void Complete0()
 {
     this.attemptInfo = strategy.AddToWindow(this.attemptInfo.Message, this.isLast, this.attemptInfo.State);
 }
        void OnRetryTimeoutElapsed(MessageAttemptInfo attemptInfo)
        {
            if (this.sendGuard.Enter())
            {
                IAsyncResult result = this.beginSendHandler(attemptInfo, this.sendTimeout, true, onSendRetryComplete, this);

                if (result.CompletedSynchronously)
                {
                    this.CompleteSendRetry(result);
                }
            }
        }
        // Must call in a lock(this.ThisLock).
        MessageAttemptInfo AddToWindow(Message message, bool isLast, object state)
        {
            MessageAttemptInfo attemptInfo = default(MessageAttemptInfo);
            Int64 sequenceNumber;

            sequenceNumber = this.windowStart + this.window.Count;
            WsrmUtilities.AddSequenceHeader(this.reliableMessagingVersion, message, this.id, sequenceNumber, isLast);

            if (this.requestAcks && (this.window.Count == this.windowSize - 1 || this.quotaRemaining == 1)) // can't add any more
            {
                message.Properties.AllowOutputBatching = false;
                WsrmUtilities.AddAckRequestedHeader(this.reliableMessagingVersion, message, this.id);
            }

            if (this.window.Count == 0)
            {
                this.retryTimer.Set(this.Timeout);
            }

            this.window.Add(message, Now, state);
            this.quotaRemaining--;
            if (isLast)
                this.last = sequenceNumber;

            int index = (int)(sequenceNumber - this.windowStart);
            attemptInfo = new MessageAttemptInfo(this.window.GetMessage(index), sequenceNumber, 0, state);

            return attemptInfo;
        }