Example #1
0
 void Register0(TaskCompletionSource promise)
 {
     try
     {
         // check if the channel is still open as it could be closed input the mean time when the register
         // call was outside of the eventLoop
         if (!promise.SetUncancellable() || !EnsureOpen(promise))
         {
             PromiseUtil.SafeSetFailure(promise, ClosedChannelException.Instance, Logger);
             return;
         }
         bool firstRegistration = this.neverRegistered;
         this._channel.DoRegister();
         this.neverRegistered      = false;
         this._channel._registered = true;
         this._channel._eventLoop.AcceptNewTasks();
         PromiseUtil.SafeSetSuccess(promise, Logger);
         _channel._pipeline.FireChannelRegistered();
         // Only fire a channelActive if the channel has never been registered. This prevents firing
         // multiple channel actives if the channel is deregistered and re-registered.
         if (firstRegistration && this._channel.IsActive)
         {
             _channel._pipeline.FireChannelActive();
         }
     }
     catch (Exception t)
     {
         // Close the channel directly to avoid FD leak.
         CloseForcibly();
         _channel._closeTask.Complete();
         PromiseUtil.SafeSetFailure(promise, t, Logger);
     }
 }
Example #2
0
            public Task BindAsync(EndPoint localAddress)
            {
                // todo: cancellation support
                if (/*!promise.setUncancellable() || */ !_channel.IsOpen)
                {
                    return(CreateClosedChannelExceptionTask());
                }


                bool wasActive = this._channel.IsActive;
                var  promise   = new TaskCompletionSource();

                try
                {
                    this._channel.DoBind(localAddress);
                }
                catch (Exception t)
                {
                    PromiseUtil.SafeSetFailure(promise, t, Logger);
                    this.CloseIfClosed();
                    return(promise.Task);
                }

                if (!wasActive && _channel.IsActive)
                {
                    InvokeLater(() => this._channel._pipeline.FireChannelActive());
                }

                SafeSetSuccess(promise);

                return(promise.Task);
            }
        internal void Close(ClosedChannelException cause)
        {
            if (_inFail)
            {
                return;
            }

            if (!IsEmpty)
            {
                throw new InvalidOperationException("close() must be called after all flushed writes are handled.");
            }

            _inFail = true;

            try
            {
                var e = _unflushedEntry;
                while (e != null)
                {
                    // No triggering anymore events, as we are shutting down
                    if (!e.Cancelled)
                    {
                        ReferenceCountUtil.SafeRelease(e.Message);
                        PromiseUtil.SafeSetFailure(e.Promise, cause, Logger);
                    }
                    e = e.RecycleAndGetNext();
                }
            }
            finally
            {
                _inFail = false;
            }
        }
        private bool Remove(Exception cause, bool notifyWritability)
        {
            var e = _flushedEntry;

            if (e == null)
            {
                return(false);
            }
            var msg     = e.Message;
            var promise = e.Promise;
            var size    = e.PendingSize;

            RemoveEntry(e);

            if (!e.Cancelled)
            {
                // only release message, notify and decrement if it was not canceled before.
                ReferenceCountUtil.SafeRelease(msg);
                PromiseUtil.SafeSetFailure(promise, cause, Logger);
                DecrementPendingOutboundBytes(size, notifyWritability);
            }

            e.Recycle();
            return(true);
        }
        public bool Remove()
        {
            var e = _flushedEntry;

            if (e == null)
            {
                return(false);
            }
            var msg     = e.Message;
            var promise = e.Promise;
            var size    = e.PendingSize;

            RemoveEntry(e);

            if (!e.Cancelled)
            {
                // only release message, notify and decrement if it was not canceled before.
                ReferenceCountUtil.SafeRelease(msg);
                PromiseUtil.SafeSetSuccess(promise, Logger);
                DecrementPendingOutboundBytes(size, true);
            }

            e.Recycle();
            return(true);
        }
Example #6
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._closeTask.Task);
                    }
                    return(promise.Task);
                }

                if (this._channel._closeTask.Task.IsCompleted)
                {
                    // Closed already.
                    PromiseUtil.SafeSetSuccess(promise, Logger);
                    return(promise.Task);
                }

                bool wasActive = this._channel.IsActive;
                ChannelOutboundBuffer buffer = this.outboundBuffer;

                this.outboundBuffer = null; // Disallow adding any messages and flushes to outboundBuffer.

                try
                {
                    // Close the channel and fail the queued messages input all cases.
                    this.DoClose0(promise);
                }
                finally
                {
                    // Fail all the queued messages.
                    buffer.FailFlushed(ClosedChannelException.Instance, false);
                    buffer.Close(ClosedChannelException.Instance);
                }
                if (this.inFlush0)
                {
                    this.InvokeLater(() => this.FireChannelInactiveAndDeregister(wasActive));
                }
                else
                {
                    this.FireChannelInactiveAndDeregister(wasActive);
                }


                return(promise.Task);
            }
Example #7
0
            protected bool EnsureOpen(TaskCompletionSource promise)
            {
                if (this._channel.IsOpen)
                {
                    return(true);
                }

                PromiseUtil.SafeSetFailure(promise, ClosedChannelException.Instance, Logger);
                return(false);
            }
Example #8
0
            public Task RegisterAsync(IEventLoop eventLoop)
            {
                Contract.Requires(eventLoop != null);
                if (this._channel.Registered)
                {
                    return(TaskEx.FromException(new InvalidOperationException("registered to an event loop already")));
                }
                if (!this._channel.IsCompatible(eventLoop))
                {
                    return
                        (TaskEx.FromException(
                             new InvalidOperationException("incompatible event loop type: " + eventLoop.GetType().Name)));
                }

                // It's necessary to reuse the wrapped eventloop object. Otherwise the user will end up with multiple
                // objects that do not share a common state.
                if (this._channel._eventLoop == null)
                {
                    this._channel._eventLoop = new PausableChannelEventLoop(this._channel, eventLoop);
                }
                else
                {
                    this._channel._eventLoop.Unwrapped = eventLoop;
                }

                var promise = new TaskCompletionSource();

                if (eventLoop.InEventLoop)
                {
                    this.Register0(promise);
                }
                else
                {
                    try
                    {
                        eventLoop.Execute(() => this.Register0(promise));
                    }
                    catch (Exception ex)
                    {
                        Logger.Warning(
                            "Force-closing a channel whose registration task was not accepted by an event loop: {0}; Cause: {1}",
                            _channel,
                            ex);
                        CloseForcibly();
                        _channel._closeTask.TryComplete();
                        PromiseUtil.SafeSetFailure(promise, ex, Logger);
                    }
                }

                return(promise.Task);
            }
Example #9
0
            public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
            {
                if (Local._state == State.Connected)
                {
                    var cause = new AlreadyConnectedException();
                    Local.Pipeline.FireExceptionCaught(cause);
                    return(TaskEx.FromException(cause));
                }

                if (Local._connectPromise != null)
                {
                    throw new ConnectionPendingException();
                }

                Local._connectPromise = new TaskCompletionSource();
                if (Local._state != State.Bound)
                {
                    // Not bound yet and no LocalAddress specified. Get one
                    if (localAddress == null)
                    {
                        localAddress = new LocalAddress(Local);
                    }
                }

                if (localAddress != null)
                {
                    try
                    {
                        Local.DoBind(localAddress);
                    }
                    catch (Exception ex)
                    {
                        PromiseUtil.SafeSetFailure(Local._connectPromise, ex, Logger);
                        return(CloseAsync());
                    }
                }

                var boundChannel = LocalChannelRegistry.Get(remoteAddress);

                if (!(boundChannel is LocalServerChannel))
                {
                    var cause = new ChannelException("connection refused");
                    PromiseUtil.SafeSetFailure(Local._connectPromise, cause, Logger);
                    return(CloseAsync());
                }

                var serverChannel = boundChannel as LocalServerChannel;

                Local._peer = serverChannel.Serve(Local);
                return(TaskEx.Completed);
            }
Example #10
0
 public void SafeSetSuccess(TaskCompletionSource promise)
 {
     PromiseUtil.SafeSetSuccess(promise, Logger);
 }
Example #11
0
 static void SafeSetFailure(TaskCompletionSource promise, Exception cause)
 {
     PromiseUtil.SafeSetFailure(promise, cause, Logger);
 }