Ejemplo n.º 1
0
        public Task InvokeWriteAsync(IChannelHandlerContext ctx, object msg)
        {
            Contract.Requires(msg != null);
            // todo: check for cancellation
            //if (!validatePromise(ctx, promise, false)) {
            //    // promise cancelled
            //    return;
            //}

            if (this.executor.InEventLoop)
            {
                return(ChannelHandlerInvokerUtil.InvokeWriteAsyncNow(ctx, msg));
            }
            else
            {
                var channel = (AbstractChannel)ctx.Channel;
                int size    = channel.EstimatorHandle.Size(msg);
                if (size > 0)
                {
                    ChannelOutboundBuffer buffer = channel.Unsafe.OutboundBuffer;
                    // Check for null as it may be set to null if the channel is closed already
                    if (buffer != null)
                    {
                        buffer.IncrementPendingOutboundBytes(size);
                    }
                }
                return(this.SafeProcessOutboundMessageAsync(InvokeWriteAsyncFunc, ctx, msg));
            }
        }
Ejemplo n.º 2
0
            public static WriteTask NewInstance(
                IChannelHandlerContext ctx, object msg, TaskCompletionSource promise)
            {
                WriteTask task = Recycler.Take();

                task.ctx     = ctx;
                task.msg     = msg;
                task.promise = promise;

                if (EstimateTaskSizeOnSubmit)
                {
                    ChannelOutboundBuffer buffer = ctx.Channel.Unsafe.OutboundBuffer;

                    // Check for null as it may be set to null if the channel is closed already
                    if (buffer != null)
                    {
                        task.size = ((AbstractChannel)ctx.Channel).EstimatorHandle.Size(msg) + WriteTaskOverhead;
                        buffer.IncrementPendingOutboundBytes(task.size);
                    }
                    else
                    {
                        task.size = 0;
                    }
                }
                else
                {
                    task.size = 0;
                }

                return(task);
            }
            protected static void Init(AbstractWriteTask task, AbstractChannelHandlerContext ctx, object msg, TaskCompletionSource promise)
            {
                task.ctx     = ctx;
                task.msg     = msg;
                task.promise = promise;

                if (EstimateTaskSizeOnSubmit)
                {
                    ChannelOutboundBuffer buffer = ctx.Channel.Unsafe.OutboundBuffer;

                    // Check for null as it may be set to null if the channel is closed already
                    if (buffer != null)
                    {
                        task.size = ctx.pipeline.EstimatorHandle.Size(msg) + WriteTaskOverhead;
                        buffer.IncrementPendingOutboundBytes(task.size);
                    }
                    else
                    {
                        task.size = 0;
                    }
                }
                else
                {
                    task.size = 0;
                }
            }
Ejemplo n.º 4
0
        public PendingWriteQueue(IChannelHandlerContext ctx)
        {
            Contract.Requires(ctx != null);

            this.ctx = ctx;
            this.buffer = ctx.Channel.Unsafe.OutboundBuffer;
            this.estimatorHandle = ctx.Channel.Configuration.MessageSizeEstimator.NewHandle();
        }
Ejemplo n.º 5
0
        public PendingWriteQueue(IChannelHandlerContext ctx)
        {
            Contract.Requires(ctx != null);

            this.ctx             = ctx;
            this.buffer          = ctx.Channel.Unsafe.OutboundBuffer;
            this.estimatorHandle = ctx.Channel.Configuration.MessageSizeEstimator.NewHandle();
        }
Ejemplo n.º 6
0
            public void Flush()
            {
                ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;

                if (outboundBuffer == null)
                {
                    return;
                }

                outboundBuffer.AddFlush();
                this.Flush0();
            }
Ejemplo n.º 7
0
        public BatchingPendingWriteQueue(IChannelHandlerContext ctx, int maxSize)
        {
            if (ctx is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.ctx);
            }

            _ctx             = ctx;
            _maxSize         = maxSize;
            _buffer          = ctx.Channel.Unsafe.OutboundBuffer;
            _estimatorHandle = ctx.Channel.Configuration.MessageSizeEstimator.NewHandle();
        }
Ejemplo n.º 8
0
            protected virtual void Flush0()
            {
                if (this.inFlush0)
                {
                    // Avoid re-entrance
                    return;
                }

                ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;

                if (outboundBuffer == null || outboundBuffer.IsEmpty)
                {
                    return;
                }

                this.inFlush0 = true;

                // Mark all pending write requests as failure if the channel is inactive.
                if (!this.CanWrite)
                {
                    try
                    {
                        if (this.channel.Open)
                        {
                            outboundBuffer.FailFlushed(NotYetConnectedException, true);
                        }
                        else
                        {
                            // Do not trigger channelWritabilityChanged because the channel is closed already.
                            outboundBuffer.FailFlushed(new ClosedChannelException(), false);
                        }
                    }
                    finally
                    {
                        this.inFlush0 = false;
                    }
                    return;
                }

                try
                {
                    this.channel.DoWrite(outboundBuffer);
                }
                catch (Exception ex)
                {
                    Util.CompleteChannelCloseTaskSafely(this.channel, this.CloseAsync(new ClosedChannelException("Failed to write", ex), false));
                }
                finally
                {
                    this.inFlush0 = false;
                }
            }
Ejemplo n.º 9
0
            protected virtual void Flush0()
            {
                if (this.inFlush0)
                {
                    // Avoid re-entrance
                    return;
                }

                ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;

                if (outboundBuffer == null || outboundBuffer.IsEmpty)
                {
                    return;
                }

                this.inFlush0 = true;

                // Mark all pending write requests as failure if the channel is inactive.
                if (!this.channel.Active)
                {
                    try
                    {
                        if (this.channel.Open)
                        {
                            outboundBuffer.FailFlushed(NotYetConnectedException, true);
                        }
                        else
                        {
                            // Do not trigger channelWritabilityChanged because the channel is closed already.
                            outboundBuffer.FailFlushed(ClosedChannelException, false);
                        }
                    }
                    finally
                    {
                        this.inFlush0 = false;
                    }
                    return;
                }

                try
                {
                    this.channel.DoWrite(outboundBuffer);
                }
                catch (Exception t)
                {
                    outboundBuffer.FailFlushed(t, true);
                }
                finally
                {
                    this.inFlush0 = false;
                }
            }
Ejemplo n.º 10
0
            public void Flush()
            {
                AssertEventLoop();

                ChannelOutboundBuffer outboundBuffer = Volatile.Read(ref _outboundBuffer);

                if (outboundBuffer is null)
                {
                    return;
                }

                outboundBuffer.AddFlush();
                Flush0();
            }
Ejemplo n.º 11
0
            public void Flush()
            {
                this.AssertEventLoop();

                ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;

                if (outboundBuffer == null)
                {
                    return;
                }

                outboundBuffer.AddFlush();
                this.Flush0();
            }
Ejemplo n.º 12
0
 public void Run()
 {
     try
     {
         ChannelOutboundBuffer buffer = this.ctx.Channel.Unsafe.OutboundBuffer;
         // Check for null as it may be set to null if the channel is closed already
         if (EstimateTaskSizeOnSubmit)
         {
             buffer?.DecrementPendingOutboundBytes(this.size);
         }
         ChannelHandlerInvokerUtil.InvokeWriteNowAsync(this.ctx, this.msg).LinkOutcome(this.promise);
     }
     finally
     {
         // Set to null so the GC can collect them directly
         this.ctx     = null;
         this.msg     = null;
         this.promise = null;
     }
 }
        public Task InvokeWriteAsync(IChannelHandlerContext ctx, object msg)
        {
            Contract.Requires(msg != null);
            // todo: check for cancellation
            //if (!validatePromise(ctx, promise, false)) {
            //    // promise cancelled
            //    return;
            //}

            if (this.executor.InEventLoop)
            {
                return(ChannelHandlerInvokerUtil.InvokeWriteAsyncNow(ctx, msg));
            }
            else
            {
                var channel = (AbstractChannel)ctx.Channel;
                var promise = new TaskCompletionSource(ctx);

                try
                {
                    int size = channel.EstimatorHandle.Size(msg);
                    if (size > 0)
                    {
                        ChannelOutboundBuffer buffer = channel.Unsafe.OutboundBuffer;
                        // Check for null as it may be set to null if the channel is closed already
                        if (buffer != null)
                        {
                            buffer.IncrementPendingOutboundBytes(size);
                        }
                    }

                    this.executor.Execute(InvokeWriteAsyncAction, promise, msg);
                }
                catch (Exception cause)
                {
                    ReferenceCountUtil.Release(msg); // todo: safe release?
                    promise.TrySetException(cause);
                }
                return(promise.Task);
            }
        }
Ejemplo n.º 14
0
            public Task WriteAsync(object msg)
            {
                this.AssertEventLoop();

                ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;

                if (outboundBuffer == null)
                {
                    // If the outboundBuffer is null we know the channel was closed and so
                    // need to fail the future right away. If it is not null the handling of the rest
                    // will be done input flush0()
                    // See https://github.com/netty/netty/issues/2362

                    // release message now to prevent resource-leak
                    ReferenceCountUtil.Release(msg);
                    return(TaskEx.FromException(new ClosedChannelException()));
                }

                int size;

                try
                {
                    msg  = this.channel.FilterOutboundMessage(msg);
                    size = this.channel.pipeline.EstimatorHandle.Size(msg);
                    if (size < 0)
                    {
                        size = 0;
                    }
                }
                catch (Exception t)
                {
                    ReferenceCountUtil.Release(msg);

                    return(TaskEx.FromException(t));
                }

                var promise = new TaskCompletionSource();

                outboundBuffer.AddMessage(msg, size, promise);
                return(promise.Task);
            }
Ejemplo n.º 15
0
            public void Write(object msg, IPromise promise)
            {
                AssertEventLoop();

                ChannelOutboundBuffer outboundBuffer = Volatile.Read(ref _outboundBuffer);

                if (outboundBuffer is null)
                {
                    // If the outboundBuffer is null we know the channel was closed and so
                    // need to fail the future right away. If it is not null the handling of the rest
                    // will be done input flush0()
                    // See https://github.com/netty/netty/issues/2362
                    Util.SafeSetFailure(promise, WriteClosedChannelException, Logger);
                    // release message now to prevent resource-leak
                    _ = ReferenceCountUtil.Release(msg);
                    return;
                }

                int size;

                try
                {
                    var ch = _channel;
                    msg  = ch.FilterOutboundMessage(msg);
                    size = ch._pipeline.EstimatorHandle.Size(msg);
                    if (size < 0)
                    {
                        size = 0;
                    }
                }
                catch (Exception t)
                {
                    Util.SafeSetFailure(promise, t, Logger);
                    _ = ReferenceCountUtil.Release(msg);
                    return;
                }

                outboundBuffer.AddMessage(msg, size, promise);
            }
Ejemplo n.º 16
0
 /// <summary>
 /// Flush the content of the given buffer to the remote peer.
 /// </summary>
 protected abstract void DoWrite(ChannelOutboundBuffer input);
Ejemplo n.º 17
0
            protected Task CloseAsync(Exception cause, bool notify)
            {
                var promise = new TaskCompletionSource();

                if (!promise.SetUncancellable())
                {
                    return(promise.Task);
                }

                ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;

                if (outboundBuffer == null)
                {
                    // Only needed if no VoidChannelPromise.
                    if (promise != TaskCompletionSource.Void)
                    {
                        // This means close() was called before so we just register a listener and return
                        return(this.channel.closeFuture.Task);
                    }
                    return(promise.Task);
                }

                if (this.channel.closeFuture.Task.IsCompleted)
                {
                    // Closed already.
                    Util.SafeSetSuccess(promise, Logger);
                    return(promise.Task);
                }

                bool wasActive = this.channel.Active;

                this.outboundBuffer = null;          // Disallow adding any messages and flushes to outboundBuffer.
                IEventExecutor closeExecutor = null; // todo closeExecutor();

                if (closeExecutor != null)
                {
                    closeExecutor.Execute(() =>
                    {
                        try
                        {
                            // Execute the close.
                            this.DoClose0(promise);
                        }
                        finally
                        {
                            // Call invokeLater so closeAndDeregister is executed input the EventLoop again!
                            this.InvokeLater(() =>
                            {
                                // Fail all the queued messages
                                outboundBuffer.FailFlushed(cause, notify);
                                outboundBuffer.Close(new ClosedChannelException());
                                this.FireChannelInactiveAndDeregister(wasActive);
                            });
                        }
                    });
                }
                else
                {
                    try
                    {
                        // Close the channel and fail the queued messages input all cases.
                        this.DoClose0(promise);
                    }
                    finally
                    {
                        // Fail all the queued messages.
                        outboundBuffer.FailFlushed(cause, notify);
                        outboundBuffer.Close(new ClosedChannelException());
                    }
                    if (this.inFlush0)
                    {
                        this.InvokeLater(() => this.FireChannelInactiveAndDeregister(wasActive));
                    }
                    else
                    {
                        this.FireChannelInactiveAndDeregister(wasActive);
                    }
                }

                return(promise.Task);
            }
Ejemplo n.º 18
0
            public Task CloseAsync() //CancellationToken cancellationToken)
            {
                var promise = new TaskCompletionSource();
                if (!promise.setUncancellable())
                {
                    return promise.Task;
                }
                //if (cancellationToken.IsCancellationRequested)
                //{
                //    return TaskEx.Cancelled;
                //}

                if (this.outboundBuffer == null)
                {
                    // Only needed if no VoidChannelPromise.
                    if (promise != TaskCompletionSource.Void)
                    {
                        // This means close() was called before so we just register a listener and return
                        return this.channel.closeFuture.Task;
                    }
                    return promise.Task;
                }

                if (this.channel.closeFuture.Task.IsCompleted)
                {
                    // Closed already.
                    Util.SafeSetSuccess(promise);
                    return promise.Task;
                }

                bool wasActive = this.channel.Active;
                ChannelOutboundBuffer buffer = this.outboundBuffer;
                this.outboundBuffer = null; // Disallow adding any messages and flushes to outboundBuffer.
                IEventExecutor closeExecutor = null; // todo closeExecutor();
                if (closeExecutor != null)
                {
                    closeExecutor.Execute(() =>
                    {
                        try
                        {
                            // Execute the close.
                            this.DoClose0(promise);
                        }
                        finally
                        {
                            // Call invokeLater so closeAndDeregister is executed input the EventLoop again!
                            this.InvokeLater(() =>
                            {
                                // Fail all the queued messages
                                buffer.FailFlushed(ClosedChannelException,
                                    false);
                                buffer.Close(ClosedChannelException);
                                this.FireChannelInactiveAndDeregister(wasActive);
                            });
                        }
                    });
                }
                else
                {
                    try
                    {
                        // Close the channel and fail the queued messages input all cases.
                        this.DoClose0(promise);
                    }
                    finally
                    {
                        // Fail all the queued messages.
                        buffer.FailFlushed(ClosedChannelException, false);
                        buffer.Close(ClosedChannelException);
                    }
                    if (this.inFlush0)
                    {
                        this.InvokeLater(() => this.FireChannelInactiveAndDeregister(wasActive));
                    }
                    else
                    {
                        this.FireChannelInactiveAndDeregister(wasActive);
                    }
                }

                return promise.Task;
            }
Ejemplo n.º 19
0
            //public ChannelHandlerInvoker invoker() {
            //    // return the unwrapped invoker.
            //    return ((PausableChannelEventExecutor) eventLoop().asInvoker()).unwrapInvoker();
            //}

            protected AbstractUnsafe(AbstractChannel channel)
            {
                this.channel        = channel;
                this.outboundBuffer = new ChannelOutboundBuffer(channel);
            }
Ejemplo n.º 20
0
 public CloseChannelTask(ChannelOutboundBuffer buf, Exception cause, bool allowChannelOpen)
 {
     this.buf              = buf;
     this.cause            = cause;
     this.allowChannelOpen = allowChannelOpen;
 }
Ejemplo n.º 21
0
            //public ChannelHandlerInvoker invoker() {
            //    // return the unwrapped invoker.
            //    return ((PausableChannelEventExecutor) eventLoop().asInvoker()).unwrapInvoker();
            //}

            protected AbstractUnsafe(AbstractChannel channel)
            {
                this.channel = channel;
                this.outboundBuffer = new ChannelOutboundBuffer(channel);
            }
Ejemplo n.º 22
0
            protected virtual void Flush0()
            {
                if (_inFlush0)
                {
                    // Avoid re-entrance
                    return;
                }

                ChannelOutboundBuffer outboundBuffer = Volatile.Read(ref _outboundBuffer);

                if (outboundBuffer is null || outboundBuffer.IsEmpty)
                {
                    return;
                }

                _inFlush0 = true;

                var ch = _channel;

                // Mark all pending write requests as failure if the channel is inactive.
                if (!CanWrite)
                {
                    try
                    {
                        if (ch.Open)
                        {
                            outboundBuffer.FailFlushed(Flush0NotYetConnectedException, true);
                        }
                        else
                        {
                            // Do not trigger channelWritabilityChanged because the channel is closed already.
                            outboundBuffer.FailFlushed(Flush0ClosedChannelException, false);
                        }
                    }
                    finally
                    {
                        _inFlush0 = false;
                    }
                    return;
                }

                try
                {
                    ch.DoWrite(outboundBuffer);
                }
                catch (Exception ex)
                {
                    //if (ch.Configuration.AutoClose)
                    //{

                    /*
                     * Just call {@link #close(ChannelPromise, Throwable, boolean)} here which will take care of
                     * failing all flushed messages and also ensure the actual close of the underlying transport
                     * will happen before the promises are notified.
                     *
                     * This is needed as otherwise {@link #isActive()} , {@link #isOpen()} and {@link #isWritable()}
                     * may still return <c>true</c> even if the channel should be closed as result of the exception.
                     */
                    Close(VoidPromise(), ex, Flush0ClosedChannelException, false);
                    //}
                    //else
                    //{
                    //    try
                    //    {
                    //        shutdownOutput(voidPromise(), t);
                    //    }
                    //    catch(Exception ex2)
                    //    {
                    //        close(voidPromise(), t2, FLUSH0_CLOSED_CHANNEL_EXCEPTION, false);
                    //    }
                    //}
                }
                finally
                {
                    _inFlush0 = false;
                }
            }
Ejemplo n.º 23
0
 private void CloseOutboundBufferForShutdown(IChannelPipeline pipeline, ChannelOutboundBuffer buffer, Exception cause)
 {
     buffer.FailFlushed(cause, false);
     buffer.Close(cause, true);
     _ = pipeline.FireUserEventTriggered(ChannelOutputShutdownEvent.Instance);
 }
Ejemplo n.º 24
0
 /// <summary>
 /// Flush the content of the given buffer to the remote peer.
 /// </summary>
 protected abstract void DoWrite(ChannelOutboundBuffer input);
Ejemplo n.º 25
0
        //protected override IChannelUnsafe NewUnsafe() => new DefaultServerUnsafe(this);

        protected override void DoWrite(ChannelOutboundBuffer buf) => throw new NotSupportedException();