예제 #1
0
        private Task <bool> RemoveAsyncIfSupported(TKey key)
        {
            if (key is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
            }

            if (_map.TryRemove(key, out TPool pool))
            {
                var removePromise = new TaskCompletionSource <bool>();
                PoolCloseAsyncIfSupported(pool).ContinueWith((t, s) =>
                {
                    if (t.IsSuccess())
                    {
                        ((TaskCompletionSource <bool>)s).TrySetResult(true);
                    }
                    else
                    {
                        ((TaskCompletionSource <bool>)s).TrySetException(TaskUtil.Unwrap(t.Exception));
                    }
                },
                                                             removePromise
#if !NET451
                                                             , TaskContinuationOptions.RunContinuationsAsynchronously
#endif
                                                             );
                return(removePromise.Task);
            }
            return(TaskUtil.False);
        }
예제 #2
0
 private static void FireContextExceptionOnFailure(Task t, object s)
 {
     if (t.IsFault())
     {
         _ = ((IChannelHandlerContext)s).FireExceptionCaught(TaskUtil.Unwrap(t.Exception));
     }
 }
예제 #3
0
 private static void FirePipelineExceptionOnFailure(Task t, object s)
 {
     if (t.IsFault())
     {
         _ = ((IChannelPipeline)s).FireExceptionCaught(TaskUtil.Unwrap(t.Exception));
     }
 }
예제 #4
0
 public static Task FireExceptionOnFailure(this Task task, IChannelHandlerContext ctx)
 {
     if (task.IsCompleted)
     {
         if (task.IsFault())
         {
             _ = ctx.FireExceptionCaught(TaskUtil.Unwrap(task.Exception));
         }
         return(TaskUtil.Completed);
     }
     else
     {
         return(task.ContinueWith(FireContextExceptionOnFailureAction, ctx, TaskContinuationOptions.ExecuteSynchronously));
     }
 }
예제 #5
0
 public static Task FireExceptionOnFailure(this Task task, IChannelPipeline pipeline)
 {
     if (task.IsCompleted)
     {
         if (task.IsFault())
         {
             _ = pipeline.FireExceptionCaught(TaskUtil.Unwrap(task.Exception));
         }
         return(TaskUtil.Completed);
     }
     else
     {
         return(task.ContinueWith(FirePipelineExceptionOnFailureAction, pipeline, TaskContinuationOptions.ExecuteSynchronously));
     }
 }
예제 #6
0
        public void TestFlushCloseReentrance()
        {
            var      group  = new MultithreadEventLoopGroup(1);
            var      socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
            IChannel sc     = null;

            try
            {
                var futures = new BlockingCollection <Task>();

                ServerBootstrap sb = new ServerBootstrap();
                sb.Group(group)
                .Channel <TcpServerSocketChannel>()
                .Option(ChannelOption.SoSndbuf, 1024)
                .ChildHandler(new ChannelInboundHandlerAdapter1(futures));

                sc = sb.BindAsync(new IPEndPoint(IPAddress.Loopback, 0)).GetAwaiter().GetResult();
#if NET452
                socket.Connect(sc.LocalAddress);
#else
                socket.ConnectAsync(sc.LocalAddress).GetAwaiter().GetResult();
#endif

                byte[] tempArea = new byte[8192];
#if NETCOREAPP_2_0_GREATER || NETSTANDARD_2_0_GREATER
                Span <byte> buf = tempArea;
#endif
                while (true)
                {
#if NETCOREAPP_2_0_GREATER || NETSTANDARD_2_0_GREATER
                    var byteCount = socket.Receive(buf);
#else
                    var byteCount = socket.Receive(tempArea);
#endif
                    if (byteCount <= 0)
                    {
                        break;
                    }

                    // Wait a little bit so that the write attempts are split into multiple flush attempts.
                    Thread.Sleep(10);
                }
                SocketEx.SafeClose(socket);

                Assert.Equal(3, futures.Count);
                var f1 = futures.Take();
                var f2 = futures.Take();
                var f3 = futures.Take();
                Assert.True(f1.IsSuccess());
                Assert.True(f1.IsCompleted);
                Assert.False(f2.IsSuccess());
                Assert.True(f2.IsCompleted);
                Assert.IsType <ClosedChannelException>(TaskUtil.Unwrap(f2.Exception));
                Assert.False(f3.IsSuccess());
                Assert.True(f3.IsCompleted);
                Assert.IsType <ClosedChannelException>(TaskUtil.Unwrap(f3.Exception));
            }
            finally
            {
                SocketEx.SafeClose(socket);
                sc?.CloseAsync().GetAwaiter().GetResult();
                group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)).GetAwaiter().GetResult();
            }
        }