public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
            {
                var ch = (NativeChannel)this.channel;

                if (!ch.Open)
                {
                    return(this.CreateClosedChannelExceptionTask());
                }

                try
                {
                    if (ch.connectPromise != null)
                    {
                        throw new InvalidOperationException("connection attempt already made");
                    }

                    ch.connectPromise = new TaskCompletionSource(remoteAddress);

                    // Schedule connect timeout.
                    TimeSpan connectTimeout = ch.Configuration.ConnectTimeout;
                    if (connectTimeout > TimeSpan.Zero)
                    {
                        ch.connectCancellationTask = ch.EventLoop
                                                     .Schedule(CancelConnect, ch, remoteAddress, connectTimeout);
                    }

                    ch.DoConnect(remoteAddress, localAddress);
                    return(ch.connectPromise.Task);
                }
                catch (Exception ex)
                {
                    this.CloseIfClosed();
                    return(TaskEx.FromException(this.AnnotateConnectException(ex, remoteAddress)));
                }
            }
示例#2
0
            public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
            {
                NativeChannel ch = this.Channel;

                if (!ch.Open)
                {
                    return(this.CreateClosedChannelExceptionTask());
                }

                ConnectRequest request = null;

                try
                {
                    if (ch.connectPromise != null)
                    {
                        throw new InvalidOperationException("connection attempt already made");
                    }

                    ch.connectPromise = new TaskCompletionSource(remoteAddress);

                    if (localAddress != null)
                    {
                        ch.DoBind(localAddress);
                    }
                    request = new TcpConnect(this, (IPEndPoint)remoteAddress);
                    return(ch.connectPromise.Task);
                }
                catch (Exception ex)
                {
                    request?.Dispose();
                    this.CloseIfClosed();
                    return(TaskEx.FromException(this.AnnotateConnectException(ex, remoteAddress)));
                }
            }
示例#3
0
            public Task DisconnectAsync()
            {
                this.AssertEventLoop();

                bool wasActive = this.channel.Active;

                try
                {
                    this.channel.DoDisconnect();
                }
                catch (Exception t)
                {
                    this.CloseIfClosed();
                    return(TaskEx.FromException(t));
                }

                if (wasActive && !this.channel.Active)
                {
                    this.InvokeLater(() => this.channel.pipeline.FireChannelInactive());
                }

                this.CloseIfClosed(); // doDisconnect() might have closed the channel

                return(TaskEx.Completed);
            }
示例#4
0
        /// <summary>
        /// INTERNAL API
        ///
        /// Should only be called directly by the <see cref="AppDomain.ProcessExit"/> event
        /// in production.
        ///
        /// Safe to call multiple times, but hooks will only be run once.
        /// </summary>
        /// <returns>Returns a <see cref="Task"/> that will be completed once the process exits.</returns>
        private Task <Done> RunClrHooks()
        {
            if (_clrHooksStarted.CompareAndSet(false, true))
            {
                Task.WhenAll(_clrShutdownTasks.Select(hook =>
                {
                    try
                    {
                        var t = hook();
                        return(t);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Error occurred while executing CLR shutdown hook");
                        return(TaskEx.FromException <Done>(ex));
                    }
                })).ContinueWith(tr =>
                {
                    if (tr.IsFaulted || tr.IsCanceled)
                    {
                        _hooksRunPromise.SetException(tr.Exception.Flatten());
                    }
                    else
                    {
                        _hooksRunPromise.SetResult(Done.Instance);
                    }
                });
            }

            return(ClrShutdownTask);
        }
示例#5
0
        public static void TaskExGenericFromExceptionIsFaulted()
        {
            var exception = new Exception();
            var task      = TaskEx.FromException <bool>(exception);

            Assert.IsTrue(task.IsFaulted);
        }
 public Task <IByteBuffer> GetResponseAsync()
 {
     if (_excecption != null)
     {
         return(TaskEx.FromException <IByteBuffer>(_excecption));
     }
     return(Task.FromResult(_buffer));
 }
示例#7
0
        public static void TaskExGenericFromExceptionRespectsException()
        {
            var exception = new Exception();
            var task      = TaskEx.FromException <bool>(exception);

            // ReSharper disable once PossibleNullReferenceException
            Assert.AreEqual(exception, task.Exception.InnerException);
        }
 public override Task WriteAsync(IChannelHandlerContext context, object message)
 {
     if (!(message is IByteBuffer))
     {
         return(TaskEx.FromException(new UnsupportedMessageTypeException(message, typeof(IByteBuffer))));
     }
     return(this.pendingUnencryptedWrites.Add(message));
 }
示例#9
0
 Task SafeExecuteOutboundAsync(Func <Task> task)
 {
     try
     {
         return(this.executor.SubmitAsync(task));
     }
     catch (Exception cause)
     {
         return(TaskEx.FromException(cause));
     }
 }
        public override Task WriteAsync(IChannelHandlerContext context, object message)
        {
            Contract.Requires(context != null);

            IByteBuffer buffer = null;
            Task        result;

            try
            {
                if (this.AcceptOutboundMessage(message))
                {
                    buffer = this.AllocateBuffer(context);
                    var input = (T)message;
                    try
                    {
                        this.Encode(context, input, buffer);
                    }
                    finally
                    {
                        ReferenceCountUtil.Release(input);
                    }

                    if (buffer.IsReadable())
                    {
                        result = context.WriteAsync(buffer);
                    }
                    else
                    {
                        buffer.Release();
                        result = context.WriteAsync(Unpooled.Empty);
                    }

                    buffer = null;
                }
                else
                {
                    return(context.WriteAsync(message));
                }
            }
            catch (EncoderException e)
            {
                return(TaskEx.FromException(e));
            }
            catch (Exception ex)
            {
                return(TaskEx.FromException(new EncoderException(ex)));
            }
            finally
            {
                buffer?.Release();
            }

            return(result);
        }
示例#11
0
 Task SafeProcessOutboundMessageAsync(Func <object, object, Task> task, object state, object msg)
 {
     try
     {
         return(this.executor.SubmitAsync(task, state, msg));
     }
     catch (Exception cause)
     {
         ReferenceCountUtil.Release(msg);
         return(TaskEx.FromException(cause));
     }
 }
示例#12
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);
            }
示例#13
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);
            }
示例#14
0
        /// <summary>
        /// Returns a <see cref="Task"/> that will be completed with the success or failure
        /// of the provided value after the specified duration.
        /// </summary>
        /// <typeparam name="T">The return type of task.</typeparam>
        /// <param name="duration">The duration to wait.</param>
        /// <param name="scheduler">The scheduler instance to use.</param>
        /// <param name="value">The task we're going to wrap.</param>
        /// <returns>a <see cref="Task"/> that will be completed with the success or failure
        /// of the provided value after the specified duration</returns>
        public static Task <T> After <T>(TimeSpan duration, IScheduler scheduler, Func <Task <T> > value)
        {
            if (duration < TimeSpan.MaxValue && duration.Ticks < 1)
            {
                // no need to schedule
                try
                {
                    return(value());
                }
                catch (Exception ex)
                {
                    return(TaskEx.FromException <T>(ex));
                }
            }

            var tcs = new TaskCompletionSource <T>();

            scheduler.Advanced.ScheduleOnce(duration, () =>
            {
                try
                {
                    value().ContinueWith(tr =>
                    {
                        try
                        {
                            if (tr.IsCanceled || tr.IsFaulted)
                            {
                                tcs.SetException(tr.Exception.InnerException);
                            }
                            else
                            {
                                tcs.SetResult(tr.Result);
                            }
                        }
                        catch (AggregateException ex)
                        {
                            // in case the task faults
                            tcs.SetException(ex.Flatten());
                        }
                    });
                }
                catch (Exception ex)
                {
                    // in case the value() function faults
                    tcs.SetException(ex);
                }
            });
            return(tcs.Task);
        }
        protected override Task ProcessAsync(IChannelHandlerContext context, PacketWithId packet)
        {
            TAckState message;

            if (this.TryDequeueMessage(packet, out message))
            {
                return(this.processAckFunc(context, message));
            }
            else if (this.abortOnOutOfOrderAck)
            {
                return(TaskEx.FromException(new ProtocolGatewayException(ErrorCode.InvalidPubAckOrder, "Client MUST send PUBACK packets in the order in which the corresponding PUBLISH packets were received")));
            }

            return(TaskEx.Completed);
        }
示例#16
0
        public async Task SmokeTest()
        {
            Task t1 = TaskEx.FromException(new InvalidOperationException("the message"));

            Assert.True(t1.IsFaulted);
            InvalidOperationException e1 = await Assert.ThrowsAsync <InvalidOperationException>(() => t1);

            Assert.Equal("the message", e1.Message);

            Task <int> t2 = TaskEx.FromException <int>(new BadImageFormatException("there's a bad image"));

            Assert.True(t1.IsFaulted);
            BadImageFormatException e2 = await Assert.ThrowsAsync <BadImageFormatException>(() => t2);

            Assert.Equal("there's a bad image", e2.Message);
        }
示例#17
0
        public Task HandshakeAsync(IChannel channel, IHttpRequest req, HttpHeaders responseHeaders)
        {
            if (req is IFullHttpRequest request)
            {
                return(this.HandshakeAsync(channel, request, responseHeaders));
            }
            if (Logger.DebugEnabled)
            {
                Logger.Debug("{} WebSocket version {} server handshake", channel, this.version);
            }
            IChannelPipeline       p   = channel.Pipeline;
            IChannelHandlerContext ctx = p.Context <HttpRequestDecoder>();

            if (ctx == null)
            {
                // this means the user use a HttpServerCodec
                ctx = p.Context <HttpServerCodec>();
                if (ctx == null)
                {
                    return(TaskEx.FromException(new InvalidOperationException("No HttpDecoder and no HttpServerCodec in the pipeline")));
                }
            }

            // Add aggregator and ensure we feed the HttpRequest so it is aggregated. A limit o 8192 should be more then
            // enough for the websockets handshake payload.
            //
            // TODO: Make handshake work without HttpObjectAggregator at all.
            string aggregatorName = "httpAggregator";

            p.AddAfter(ctx.Name, aggregatorName, new HttpObjectAggregator(8192));
            var completion = new TaskCompletionSource();

            p.AddAfter(aggregatorName, "handshaker", new Handshaker(this, channel, responseHeaders, completion));
            try
            {
                ctx.FireChannelRead(ReferenceCountUtil.Retain(req));
            }
            catch (Exception cause)
            {
                completion.TrySetException(cause);
            }
            return(completion.Task);
        }
示例#18
0
            public Task BindAsync(EndPoint localAddress)
            {
                this.AssertEventLoop();

                // todo: cancellation support
                if (/*!promise.setUncancellable() || */ !this.channel.Open)
                {
                    return(this.CreateClosedChannelExceptionTask());
                }

                //// See: https://github.com/netty/netty/issues/576
                //if (bool.TrueString.Equals(this.channel.Configuration.getOption(ChannelOption.SO_BROADCAST)) &&
                //    localAddress is IPEndPoint &&
                //    !((IPEndPoint)localAddress).Address.getAddress().isAnyLocalAddress() &&
                //    !Environment.OSVersion.Platform == PlatformID.Win32NT && !Environment.isRoot())
                //{
                //    // Warn a user about the fact that a non-root user can't receive a
                //    // broadcast packet on *nix if the socket is bound on non-wildcard address.
                //    logger.Warn(
                //        "A non-root user can't receive a broadcast packet if the socket " +
                //            "is not bound to a wildcard address; binding to a non-wildcard " +
                //            "address (" + localAddress + ") anyway as requested.");
                //}

                bool wasActive = this.channel.Active;

                try
                {
                    this.channel.DoBind(localAddress);
                }
                catch (Exception t)
                {
                    this.CloseIfClosed();
                    return(TaskEx.FromException(t));
                }

                if (!wasActive && this.channel.Active)
                {
                    this.InvokeLater(() => this.channel.pipeline.FireChannelActive());
                }

                return(TaskEx.Completed);
            }
        public void CoordinatedShutdown_must_continue_after_timeout_or_failure()
        {
            var phases = new Dictionary <string, Phase>()
            {
                { "a", EmptyPhase },
                { "b", new Phase(ImmutableHashSet <string> .Empty.Add("a"), TimeSpan.FromMilliseconds(100), true) },
                { "c", Phase("b", "a") }
            };

            var co = new CoordinatedShutdown(ExtSys, phases);

            co.AddTask("a", "a1", () =>
            {
                TestActor.Tell("A");
                return(TaskEx.FromException <Done>(new Exception("boom")));
            });

            co.AddTask("a", "a2", () =>
            {
                Task.Delay(TimeSpan.FromMilliseconds(100)).Wait();
                TestActor.Tell("A");
                return(TaskEx.Completed);
            });

            co.AddTask("b", "b1", () =>
            {
                TestActor.Tell("B");
                return(new TaskCompletionSource <Done>().Task); // never completed
            });

            co.AddTask("c", "c1", () =>
            {
                TestActor.Tell("C");
                return(TaskEx.Completed);
            });

            co.Run(CoordinatedShutdown.UnknownReason.Instance).Wait(RemainingOrDefault);
            ExpectMsg("A");
            ExpectMsg("A");
            ExpectMsg("B");
            ExpectMsg("C");
        }
示例#20
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);
            }
示例#21
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)));
                }

                this.channel.eventLoop = eventLoop;

                var promise = new TaskCompletionSource();

                if (eventLoop.InEventLoop)
                {
                    this.Register0(promise);
                }
                else
                {
                    try
                    {
                        eventLoop.Execute((u, p) => ((AbstractUnsafe)u).Register0((TaskCompletionSource)p), this, promise);
                    }
                    catch (Exception ex)
                    {
                        Logger.Warn("Force-closing a channel whose registration task was not accepted by an event loop: {}", this.channel, ex);
                        this.CloseForcibly();
                        this.channel.closeFuture.Complete();
                        Util.SafeSetFailure(promise, ex, Logger);
                    }
                }

                return(promise.Task);
            }
示例#22
0
        public override Task WriteAsync(IChannelHandlerContext context, object message)
        {
            if (!(message is IHttpRequest))
            {
                return(context.WriteAsync(message));
            }

            if (this.upgradeRequested)
            {
                return(TaskEx.FromException(new InvalidOperationException("Attempting to write HTTP request with upgrade in progress")));
            }

            this.upgradeRequested = true;
            this.SetUpgradeRequestHeaders(context, (IHttpRequest)message);

            // Continue writing the request.
            Task task = context.WriteAsync(message);

            // Notify that the upgrade request was issued.
            context.FireUserEventTriggered(UpgradeEvent.UpgradeIssued);
            // Now we wait for the next HTTP response to see if we switch protocols.
            return(task);
        }
示例#23
0
            /// <summary>
            /// This method must NEVER be called directly, but be executed as an
            /// extra task with a clean call stack instead. The reason for this
            /// is that this method calls {@link ChannelPipeline#fireChannelUnregistered()}
            /// directly, which might lead to an unfortunate nesting of independent inbound/outbound
            /// events. See the comments input {@link #invokeLater(Runnable)} for more details.
            /// </summary>
            public Task DeregisterAsync()
            {
                //if (!promise.setUncancellable())
                //{
                //    return;
                //}

                if (!this.channel.registered)
                {
                    return(TaskEx.Completed);
                }

                try
                {
                    this.channel.DoDeregister();
                }
                catch (Exception t)
                {
                    Logger.Warn("Unexpected exception occurred while deregistering a channel.", t);
                    return(TaskEx.FromException(t));
                }
                finally
                {
                    if (this.channel.registered)
                    {
                        this.channel.registered = false;
                        this.channel.pipeline.FireChannelUnregistered();
                    }
                    else
                    {
                        // Some transports like local and AIO does not allow the deregistration of
                        // an open channel.  Their doDeregister() calls close().  Consequently,
                        // close() calls deregister() again - no need to fire channelUnregistered.
                    }
                }
                return(TaskEx.Completed);
            }
示例#24
0
 public DefaultServerUnsafe(AbstractChannel channel)
     : base(channel)
 {
     this.err = TaskEx.FromException(new NotSupportedException());
 }
示例#25
0
 protected Task CreateClosedChannelExceptionTask() => TaskEx.FromException(new ClosedChannelException());
        public override Task WriteAsync(IChannelHandlerContext ctx, object msg)
        {
            Task result;
            ThreadLocalObjectList output = null;

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

                    if (output.Count == 0)
                    {
                        output.Return();
                        output = null;

                        throw new EncoderException(this.GetType().Name + " must produce at least one message.");
                    }
                }
                else
                {
                    return(ctx.WriteAsync(msg));
                }
            }
            catch (EncoderException e)
            {
                return(TaskEx.FromException(e));
            }
            catch (Exception ex)
            {
                return(TaskEx.FromException(new EncoderException(ex))); // todo: we don't have a stack on EncoderException but it's present on inner exception.
            }
            finally
            {
                if (output != null)
                {
                    int lastItemIndex = output.Count - 1;
                    if (lastItemIndex == 0)
                    {
                        result = ctx.WriteAsync(output[0]);
                    }
                    else if (lastItemIndex > 0)
                    {
                        for (int i = 0; i < lastItemIndex; i++)
                        {
                            // we don't care about output from these messages as failure while sending one of these messages will fail all messages up to the last message - which will be observed by the caller in Task result.
                            ctx.WriteAsync(output[i]); // todo: optimize: once IChannelHandlerContext allows, pass "not interested in task" flag
                        }
                        result = ctx.WriteAsync(output[lastItemIndex]);
                    }
                    else
                    {
                        // 0 items in output - must never get here
                        result = null;
                    }
                    output.Return();
                }
                else
                {
                    // output was reset during exception handling - must never get here
                    result = null;
                }
            }
            return(result);
        }
示例#27
0
 public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
 {
     return(TaskEx.FromException(new NotSupportedException()));
 }
 static Task ComposeExceptionTask(Exception cause) => TaskEx.FromException(cause);
示例#29
0
            public sealed override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
            {
                // todo: handle cancellation
                AbstractSocketChannel ch = this.Channel;

                if (!ch.Open)
                {
                    return(this.CreateClosedChannelExceptionTask());
                }

                try
                {
                    if (ch.connectPromise != null)
                    {
                        throw new InvalidOperationException("connection attempt already made");
                    }

                    bool wasActive = this.channel.Active;
                    if (ch.DoConnect(remoteAddress, localAddress))
                    {
                        this.FulfillConnectPromise(wasActive);
                        return(TaskEx.Completed);
                    }
                    else
                    {
                        ch.connectPromise = new TaskCompletionSource(remoteAddress);

                        // Schedule connect timeout.
                        TimeSpan connectTimeout = ch.Configuration.ConnectTimeout;
                        if (connectTimeout > TimeSpan.Zero)
                        {
                            ch.connectCancellationTask = ch.EventLoop.Schedule(
                                (c, a) =>
                            {
                                // todo: make static / cache delegate?..
                                var self = (AbstractSocketChannel)c;
                                // todo: call Socket.CancelConnectAsync(...)
                                TaskCompletionSource promise = self.connectPromise;
                                var cause = new ConnectTimeoutException("connection timed out: " + a.ToString());
                                if (promise != null && promise.TrySetException(cause))
                                {
                                    self.CloseAsync();
                                }
                            },
                                this.channel,
                                remoteAddress,
                                connectTimeout);
                        }

                        ch.connectPromise.Task.ContinueWith(
                            (t, s) =>
                        {
                            var c = (AbstractSocketChannel)s;
                            c.connectCancellationTask?.Cancel();
                            c.connectPromise = null;
                            c.CloseAsync();
                        },
                            ch,
                            TaskContinuationOptions.OnlyOnCanceled | TaskContinuationOptions.ExecuteSynchronously);

                        return(ch.connectPromise.Task);
                    }
                }
                catch (Exception ex)
                {
                    this.CloseIfClosed();
                    return(TaskEx.FromException(this.AnnotateConnectException(ex, remoteAddress)));
                }
            }
示例#30
0
 protected Task CreateClosedChannelExceptionTask()
 {
     return(TaskEx.FromException(ClosedChannelException));
 }