コード例 #1
0
        static void WriteVoidPromise(IChannelHandlerContext ctx, List <object> output)
        {
            IPromise voidPromise = ctx.VoidPromise();

            for (int i = 0; i < output.Count; i++)
            {
                _ = ctx.WriteAsync(output[i], voidPromise);
            }
        }
 public IPromise VoidPromise() => _ctx.VoidPromise();
コード例 #3
0
        /// <summary>
        /// Writes all remaining elements in this queue.
        /// </summary>
        /// <param name="ctx">The context to write all elements to.</param>
        public void WriteAndRemoveAll(IChannelHandlerContext ctx)
        {
            DecrementReadableBytes(_readableBytes);
            Exception   pending     = null;
            IByteBuffer previousBuf = null;

            while (true)
            {
                _ = _bufAndListenerPairs.TryRemoveFromFront(out var entry);
                try
                {
                    switch (entry)
                    {
                    case null:
                        if (previousBuf is object)
                        {
                            _ = ctx.WriteAsync(previousBuf, ctx.VoidPromise());
                        }
                        goto LoopEnd;

                    case IByteBuffer byteBuffer:
                        if (previousBuf is object)
                        {
                            _ = ctx.WriteAsync(previousBuf, ctx.VoidPromise());
                        }
                        previousBuf = byteBuffer;
                        break;

                    case IPromise promise:
                        _           = ctx.WriteAsync(previousBuf, promise);
                        previousBuf = null;
                        break;

                    default:
                        //    // todo
                        //    //ctx.WriteAsync(previousBuf).addListener((ChannelFutureListener)entry);
                        //    previousBuf = null;
                        break;
                    }
                }
                catch (Exception t)
                {
                    if (pending is null)
                    {
                        pending = t;
                    }
                    else
                    {
                        if (Logger.InfoEnabled)
                        {
                            Logger.ThrowableBeingSuppressedBecauseIsAlreadyPending(pending, t);
                        }
                    }
                }
            }
LoopEnd:
            if (pending is object)
            {
                _ = ThrowHelper.ThrowInvalidOperationException_CoalescingBufferQueuePending(pending);
            }
        }
コード例 #4
0
        /// <inheritdoc />
        public override void Write(IChannelHandlerContext ctx, object msg, IPromise promise)
        {
            ThreadLocalObjectList output = null;

            try
            {
                if (AcceptOutboundMessage(msg))
                {
                    output = ThreadLocalObjectList.NewInstance();
                    var cast = (T)msg;
                    try
                    {
                        Encode(ctx, cast, output);
                    }
                    finally
                    {
                        _ = ReferenceCountUtil.Release(cast);
                    }

                    if (0u >= (uint)output.Count)
                    {
                        CThrowHelper.ThrowEncoderException_MustProduceAtLeastOneMsg(GetType());
                    }
                }
                else
                {
                    _ = ctx.WriteAsync(msg, promise);
                }
            }
            catch (EncoderException)
            {
                throw;
            }
            catch (Exception ex)
            {
                CThrowHelper.ThrowEncoderException(ex); // todo: we don't have a stack on EncoderException but it's present on inner exception.
            }
            finally
            {
                if (output is object)
                {
                    try
                    {
                        int lastItemIndex = output.Count - 1;
                        if (0u >= (uint)lastItemIndex)
                        {
                            _ = ctx.WriteAsync(output[0], promise);
                        }
                        else if (lastItemIndex > 0)
                        {
                            // Check if we can use a voidPromise for our extra writes to reduce GC-Pressure
                            // See https://github.com/netty/netty/issues/2525
                            if (promise == ctx.VoidPromise())
                            {
                                WriteVoidPromise(ctx, output);
                            }
                            else
                            {
                                WritePromiseCombiner(ctx, output, promise);
                            }
                        }
                    }
                    finally
                    {
                        output.Return();
                    }
                }
            }
        }