void CancelPendingOperations(bool aborted, out Queue <AmqpMessage> messagesToRelease) { messagesToRelease = null; LinkedList <ReceiveAsyncResult> waiters = null; lock (this.SyncRoot) { messagesToRelease = this.messageQueue; waiters = this.waiterList; this.messageQueue = null; this.waiterList = null; } if (waiters != null) { ActionItem.Schedule(o => { var state = (Tuple <LinkedList <ReceiveAsyncResult>, bool>)o; LinkedList <ReceiveAsyncResult> waitersToCancel = state.Item1; foreach (ReceiveAsyncResult waiter in waitersToCancel) { if (state.Item2) { waiter.Cancel(); } else { waiter.Signal(null, false, null); } } }, new Tuple <LinkedList <ReceiveAsyncResult>, bool>(waiters, aborted)); } if (this.pendingDispositions != null) { this.pendingDispositions.Abort(); } }
bool IWorkDelegate <AmqpMessage> .Invoke(AmqpMessage message) { DeliveryState deliveryState = message.State; if (deliveryState != null && deliveryState.DescriptorCode == Released.Code) { // message has been cancelled (e.g. timed out) return(true); } bool success = this.TrySendDelivery(message); if (!success && this.Session.State == AmqpObjectState.Opened && DateTime.UtcNow - this.lastFlowRequestTime >= MinRequestCreditWindow) { // Tell the other side that we have some messages to send this.lastFlowRequestTime = DateTime.UtcNow; ActionItem.Schedule(s => OnRequestCredit(s), this); } return(success); }
void OnReceiveMessage(AmqpMessage message) { if (this.messageListener != null) { this.messageListener(message); } else { ReceiveAsyncResult waiter = null; int creditToIssue = 0; bool releaseMessage = false; lock (this.SyncRoot) { if (this.waiterList != null && this.waiterList.Count > 0) { var firstWaiter = this.waiterList.First.Value; if (this.messageQueue.IsPrefetchingBySize) { if (this.messageQueue.UpdateCreditToIssue(message)) { this.SetTotalLinkCredit(this.messageQueue.BoundedTotalLinkCredit, true); } } firstWaiter.Add(message); if (firstWaiter.RequestedMessageCount == 1 || firstWaiter.MessageCount >= firstWaiter.RequestedMessageCount) { this.waiterList.RemoveFirst(); firstWaiter.OnRemoved(); creditToIssue = this.Settings.AutoSendFlow ? 0 : this.GetOnDemandReceiveCredit(); waiter = firstWaiter; } } else if (!this.Settings.AutoSendFlow && this.Settings.SettleType != SettleMode.SettleOnSend) { releaseMessage = true; } else if (this.messageQueue != null) { this.messageQueue.Enqueue(message); AmqpTrace.Provider.AmqpCacheMessage( this, message.DeliveryId.Value, this.messageQueue.Count, this.messageQueue.IsPrefetchingBySize, this.TotalCacheSizeInBytes ?? 0, this.Settings == null ? 0 : this.Settings.TotalLinkCredit, this.LinkCredit); } } if (releaseMessage) { this.ReleaseMessage(message); message.Dispose(); } if (creditToIssue > 0) { this.IssueCredit((uint)creditToIssue, false, AmqpConstants.NullBinary); } if (waiter != null) { // Schedule the completion on another thread so we don't block the I/O thread ActionItem.Schedule(o => { var w = (ReceiveAsyncResult)o; w.Signal(false); }, waiter); } } }