/** * Dequeues one or many (or none) messages depending on the channel's auto * reading state and returns the number of messages that were consumed from * the internal queue. * * The {@code minConsume} argument is used to force {@code dequeue()} into * consuming that number of messages regardless of the channel's auto * reading configuration. * * @see #read(ChannelHandlerContext) * @see #channelRead(ChannelHandlerContext, Object) */ private int Dequeue(IChannelHandlerContext ctx, int minConsume) { int consumed = 0; // fireChannelRead(...) may call ctx.read() and so this method may reentrance. Because of this we need to // check if queue was set to null in the meantime and if so break the loop. while (_queue is object && (consumed < minConsume || _config.IsAutoRead)) { if (!_queue.TryDequeue(out object msg) || msg is null) { break; } ++consumed; _ = ctx.FireChannelRead(msg); } // We're firing a completion event every time one (or more) // messages were consumed and the queue ended up being drained // to an empty state. if (_queue is object && _queue.IsEmpty) { _queue.Recycle(); _queue = null; if (consumed > 0) { _ = ctx.FireChannelReadComplete(); } } return(consumed); }
/** * Releases all messages and destroys the {@link Queue}. */ void Destroy() { if (_queue is object) { if (_queue.NonEmpty) { #if DEBUG if (Logger.TraceEnabled) { Logger.NonEmptyQueue(_queue); } #endif if (_releaseMessages) { while (_queue.TryDequeue(out object msg)) { ReferenceCountUtil.SafeRelease(msg); } } } _queue.Recycle(); _queue = null; } }
public override void ChannelRead(IChannelHandlerContext ctx, object msg) { if (_queue is null) { _queue = Recycler.Take(); } _ = _queue.TryEnqueue(msg); // We just received one message. Do we need to relay it regardless // of the auto reading configuration? The answer is yes if this // method was called as a result of a prior read() call. int minConsume = Math.Min(_readRequestCount, _queue.Count); _readRequestCount -= minConsume; _ = Dequeue(ctx, minConsume); }
public override void ChannelRead(IChannelHandlerContext ctx, object msg) { if (this.queue == null) { this.queue = Recycler.Take(); } this.queue.TryEnqueue(msg); // We just received one message. Do we need to relay it regardless // of the auto reading configuration? The answer is yes if this // method was called as a result of a prior read() call. int minConsume = this.shouldConsume ? 1 : 0; this.shouldConsume = false; this.Dequeue(ctx, minConsume); }
/** * Releases all messages and destroys the {@link Queue}. */ void Destroy() { if (this.queue != null) { if (!this.queue.IsEmpty) { Logger.Trace($"Non-empty queue: {this.queue}"); if (this.releaseMessages) { while (this.queue.TryDequeue(out object msg)) { ReferenceCountUtil.SafeRelease(msg); } } } this.queue.Recycle(); this.queue = null; } }