From 56c5cbcb734303e180ca353b414ef057997431aa Mon Sep 17 00:00:00 2001 From: cuteant Date: Thu, 17 Sep 2020 22:09:04 +0800 Subject: [PATCH] Refactor Libuv-Transport based on NetUV --- .gitignore | 1 + DotNetty.CrossPlatform.sln | 97 ++- DotNetty.Netstandard.sln | 38 - DotNetty.sln | 38 - .../AbstractUnpooledSlicedByteBuffer.cs | 2 +- src/DotNetty.Buffers/ByteBufferUtil.Ascii.cs | 8 +- src/DotNetty.Buffers/ByteBufferUtil.Utf8.cs | 8 +- src/DotNetty.Buffers/CompositeByteBuffer.cs | 6 +- src/DotNetty.Buffers/ReadOnlyByteBuffer.cs | 4 +- .../UnpooledDuplicatedByteBuffer.cs | 4 +- .../HttpContentEncoder.cs | 4 +- src/DotNetty.Codecs.Http/HttpObjectEncoder.cs | 12 +- src/DotNetty.Codecs.Http2/Http2FrameCodec.cs | 2 +- .../Http2MultiplexHandler.cs | 2 +- .../Http2StreamFrameToHttpObjectCodec.cs | 4 +- .../InboundHttp2ToHttpAdapter.cs | 2 +- src/DotNetty.Codecs/DotNetty.Codecs.csproj | 3 - src/DotNetty.Common/DotNetty.Common.csproj | 1 + src/DotNetty.Common/Internal/Platform.cs | 26 +- .../Utilities/AsciiString.Helpers.cs | 4 +- .../Common/ServerChannelRebindHandler.cs | 140 ++-- .../DotNetty.Handlers.csproj | 1 - .../DotNetty.NetUV.Netstandard.csproj | 41 -- src/DotNetty.NetUV/DotNetty.NetUV.csproj | 44 -- .../Internal/LoggingExtensions.cs | 215 ------ src/DotNetty.NetUV/Internal/SR.cs | 75 -- .../Internal/Strings.Designer.cs | 63 -- src/DotNetty.NetUV/Internal/Strings.resx | 120 --- .../Internal/ThrowHelper.Extensions.cs | 332 --------- src/DotNetty.NetUV/Internal/ThrowHelper.cs | 247 ------- src/DotNetty.NetUV/Native/ErrorCode.cs | 245 ------- .../Native/ErrorCodeExtensions.cs | 59 -- src/DotNetty.NetUV/Native/NativeHandle.cs | 98 --- src/DotNetty.NetUV/Native/NativeMethods.cs | 261 ------- .../Native/OperationException.cs | 54 -- src/DotNetty.NetUV/Native/Platform.cs | 45 -- src/DotNetty.NetUV/Properties/AssemblyInfo.cs | 6 - src/DotNetty.NetUV/Properties/Friends.cs | 6 - src/DotNetty.NetUV/readme.md | 2 - ...LoopExecutor.cs => AbstractUVEventLoop.cs} | 40 +- .../Buffers/ReadableBuffer.cs | 2 +- .../Buffers/ReceiveBufferSizeEstimate.cs | 2 +- .../Buffers/WritableBuffer.cs | 2 +- .../Concurrency/Gate.cs | 2 +- .../DispatcherEventLoop.cs | 13 +- .../DotNetty.Transport.Libuv.csproj | 3 - .../Handles/Async.cs | 21 +- .../Handles/Check.cs | 17 +- .../Handles/FSEvent.cs | 17 +- .../Handles/FSPoll.cs | 25 +- .../Handles/FileStatus.cs | 4 +- .../Handles/HandleContext.cs | 16 +- .../Handles/IReadCompletion.cs | 4 +- .../Handles/IScheduleHandle.cs | 53 ++ .../Handles/IServerStream.cs | 25 + .../Handles}/IStreamConsumer.cs | 6 +- .../Handles/IStreamHandle.cs | 50 ++ .../Handles/IWorkHandle.cs | 21 + .../Handles/Idle.cs | 18 +- .../Handles/Loop.cs | 37 +- .../Handles/LoopContext.cs | 30 +- .../Handles/Pipe.cs | 98 +-- .../Handles/Pipeline.cs | 34 +- .../Handles/Poll.cs | 30 +- .../Handles/Prepare.cs | 17 +- .../Handles}/ReadStreamConsumer.cs | 11 +- .../Handles/ScheduleHandle (Of T).cs} | 69 +- .../Handles/ServerStream (Of T).cs} | 48 +- .../Handles/ServerStream.cs | 53 ++ .../Handles/Signal.cs | 17 +- .../Handles}/StreamConsumer.cs | 21 +- .../Handles/StreamHandle (Of T).cs} | 95 +-- .../Handles/StreamHandle.cs | 39 + .../Handles/Tcp.cs | 112 +-- .../Handles/Timer.cs | 47 +- .../Handles/Tty.cs | 43 +- .../Handles/Udp.cs | 19 +- .../Handles/WorkHandle (Of T).cs} | 54 +- .../Handles/WorkHandle.cs | 30 + .../INativeChannel.cs | 5 +- ....Extensions.cs => INativeChannelUnsafe.cs} | 33 +- .../ITcpChannelFactory.cs | 3 +- .../Internal/LoggingExtensions.cs | 187 +++-- .../Internal/Strings.Designer.cs | 6 +- .../Internal/ThrowHelper.Extensions.cs | 247 +++++-- src/DotNetty.Transport.Libuv/Native/Async.cs | 97 --- .../Native/ErrorCode.cs | 18 +- .../Native/ErrorCodeExtensions.cs | 16 +- src/DotNetty.Transport.Libuv/Native/Loop.cs | 245 ------- .../Native/NativeHandle.cs | 151 +--- .../Native/NativeMethods.Files.cs} | 4 +- .../Native/NativeMethods.Handles.cs} | 139 ++-- .../Native/NativeMethods.Loop.cs} | 10 +- .../Native/NativeMethods.Requests.cs} | 5 +- .../Native/NativeMethods.Streams.cs} | 7 +- .../Native/NativeMethods.cs | 682 +++++------------- .../Native/NativeRequest.cs | 129 ---- .../Native/OperationException.cs | 123 +--- .../Native/PendingRead.cs | 2 +- src/DotNetty.Transport.Libuv/Native/Pipe.cs | 222 ------ .../Native/PipeHandle.cs | 98 --- .../Native/PipeListener.cs | 153 ---- .../Native/PlatformApi.cs | 114 --- .../Native/PlatformApis.cs | 143 ++++ .../Native/RemoteConnection.cs | 5 +- src/DotNetty.Transport.Libuv/Native/Tcp.cs | 125 ---- .../Native/TcpConnect.cs | 56 -- .../Native/TcpHandle.cs | 129 ---- .../Native/TcpListener.cs | 98 --- src/DotNetty.Transport.Libuv/Native/Timer.cs | 133 ---- .../Native/UnixApi.cs | 18 +- .../Native/WindowsApi.cs | 32 +- .../Native/WriteRequest.cs | 208 ------ .../NativeChannel.Unsafe.cs | 33 +- src/DotNetty.Transport.Libuv/NativeChannel.cs | 16 +- .../Requests/AddressInfoRequest.cs | 17 +- .../{Native => Requests}/ConnectRequest.cs | 7 +- .../Requests}/HandleExtensions.cs | 37 +- .../Requests/NameInfoRequest.cs | 12 +- .../Requests/PipeConnect.cs | 6 +- .../Requests/PipeListener.cs | 27 + .../Requests/RequestContext.cs | 19 +- .../Requests/ScheduleRequest.cs | 4 +- .../Requests/StreamShutdown.cs | 17 +- .../Requests/TcpConnect.cs | 33 +- .../Requests/WatcherRequest.cs | 22 +- .../Requests/Work.cs | 11 +- .../Requests/WriteRequest.cs | 22 +- .../TcpChannel.Unsafe.cs | 8 +- src/DotNetty.Transport.Libuv/TcpChannel.cs | 25 +- .../TcpChannelConfig.cs | 123 ++-- .../TcpChannelFactory.cs | 1 + .../TcpServerChannel.Unsafe.cs | 24 +- .../TcpServerChannel.cs | 5 +- .../TcpServerChannelConfig.cs | 35 +- .../{EventLoop.cs => UVEventLoop.cs} | 8 +- ...actory.cs => UVEventLoopChooserFactory.cs} | 8 +- ...{EventLoopGroup.cs => UVEventLoopGroup.cs} | 49 +- .../WorkerEventLoop.cs | 77 +- .../WorkerEventLoopGroup.cs | 16 +- .../IChannelHandlerContextExtensions.cs | 4 +- .../Channels/Sockets/PlatformApis.cs | 42 -- .../Channels/Sockets/SocketEx.cs | 9 +- .../Channels/TaskExtensions.cs | 16 +- .../DotNetty.Transport.csproj | 1 - .../DotNetty.Codecs.Http2.Tests.csproj | 1 - .../DataCompressionHttp2Test.cs | 42 +- .../DotNetty.Codecs.Http2.Tests.csproj | 1 - .../Http2ConnectionRoundtripTest.cs | 58 +- .../HttpToHttp2ConnectionHandlerTest.cs | 44 +- .../InboundHttp2ToHttpAdapterTest.cs | 42 +- .../DotNetty.NetUV.Tests.csproj | 28 - .../run.netcore21.cmd | 1 - .../run.netcore31.cmd | 1 - .../DotNetty.NetUV.Tests.csproj | 25 - test/DotNetty.NetUV.Tests/run.net452.cmd | 1 - test/DotNetty.NetUV.Tests/run.net471.cmd | 1 - test/DotNetty.NetUV.Tests/run.net5.cmd | 1 - test/DotNetty.NetUV.Tests/run.netcore21.cmd | 1 - test/DotNetty.NetUV.Tests/run.netcore31.cmd | 1 - .../AutoReadTests.cs | 207 ------ .../BufReleaseTests.cs | 134 ---- .../CloseForciblyTests.cs | 78 -- .../CompositeBufferGatheringWriteTests.cs | 157 ---- .../ConnectTests.cs | 108 --- .../ConnectionAttemptTests.cs | 104 --- .../DetectPeerCloseWithoutReadTests.cs | 189 ----- .../EchoTests.cs | 202 ------ .../EventLoopTests.cs | 172 ----- .../ExceptionHandlingTests.cs | 128 ---- .../Handles/ActiveTests.cs | 4 +- .../Handles/AsyncTests.cs | 6 +- .../Handles/CallbackOrderTests.cs | 4 +- .../Handles/CloseOrderTests.cs | 6 +- .../Handles/ConnectionFailTests.cs | 6 +- .../Handles/FSEventTests.cs | 9 +- .../Handles/FSPollTests.cs | 8 +- .../Handles/GetAddrInfoTests.cs | 6 +- .../Handles/GetNameInfoTests.cs | 6 +- .../Handles/GetSockNameTests.cs | 10 +- .../Handles/IdleTests.cs | 6 +- .../Handles/LoopAliveTests.cs | 6 +- .../Handles/LoopHandleTests.cs | 4 +- .../Handles/LoopRunNoWaitTests.cs | 4 +- .../Handles/LoopRunOnceTests.cs | 4 +- .../Handles/LoopStopTests.cs | 4 +- .../Handles/LoopTimeTests.cs | 4 +- .../Handles/MultipleListenTests.cs | 4 +- .../Handles/PipeBindErrorTests.cs | 7 +- .../Handles/PipeConnectErrorTests.cs | 7 +- .../Handles/PipeConnectMultipleTests.cs | 6 +- .../Handles/PipeConnectPrepareTests.cs | 9 +- .../Handles/PipeGetSockNameTests.cs | 9 +- .../Handles/PipePendingInstancesTests.cs | 6 +- .../Handles/PipeServerCloseTests.cs | 7 +- .../Handles/PollCloseSocketTests.cs | 4 +- .../Handles/PollCloseTests.cs | 4 +- .../Handles/PollTests.cs | 11 +- .../Handles/RefTests.cs | 44 +- .../Handles/TcpBind6ErrorTests.cs | 7 +- .../Handles/TcpBindErrorTests.cs | 7 +- .../Handles/TcpCloseTests.cs | 4 +- .../Handles/TcpCloseWhileConnectingTests.cs | 6 +- .../Handles/TcpConnectTimeoutTests.cs | 6 +- .../Handles/TcpFlagsTests.cs | 4 +- .../Handles/TcpTryWriteTests.cs | 6 +- .../Handles/TestHelper.cs | 2 +- .../Handles/TimerTests.cs | 6 +- .../Handles/TtyTests.cs | 8 +- .../Handles/UdpBindTests.cs | 6 +- .../Handles/UdpDatagramTooBigTests.cs | 6 +- .../Handles/UdpIPv6Tests.cs | 16 +- .../Handles/UdpMulticastInterface6Tests.cs | 7 +- .../Handles/UdpMulticastInterfaceTests.cs | 6 +- .../Handles/UdpMulticastJoin6Tests.cs | 7 +- .../Handles/UdpMulticastJoinTests.cs | 4 +- .../Handles/UdpMulticastTtlTests.cs | 6 +- .../Handles/UdpOptionsTests.cs | 7 +- .../Handles/UdpSendAndReceiveTests.cs | 4 +- .../Handles/UdpSendImmediateTests.cs | 4 +- .../Handles/UdpSendUnreachableTests.cs | 10 +- .../Handles/UdpTrySendTests.cs | 7 +- .../ReadPendingTests.cs | 199 ----- .../ResetTests.cs | 135 ---- .../TestUtil.cs | 21 - .../WriteBeforeRegisteredTests.cs | 87 --- 226 files changed, 2303 insertions(+), 8169 deletions(-) delete mode 100644 src/DotNetty.NetUV/DotNetty.NetUV.Netstandard.csproj delete mode 100644 src/DotNetty.NetUV/DotNetty.NetUV.csproj delete mode 100644 src/DotNetty.NetUV/Internal/LoggingExtensions.cs delete mode 100644 src/DotNetty.NetUV/Internal/SR.cs delete mode 100644 src/DotNetty.NetUV/Internal/Strings.Designer.cs delete mode 100644 src/DotNetty.NetUV/Internal/Strings.resx delete mode 100644 src/DotNetty.NetUV/Internal/ThrowHelper.Extensions.cs delete mode 100644 src/DotNetty.NetUV/Internal/ThrowHelper.cs delete mode 100644 src/DotNetty.NetUV/Native/ErrorCode.cs delete mode 100644 src/DotNetty.NetUV/Native/ErrorCodeExtensions.cs delete mode 100644 src/DotNetty.NetUV/Native/NativeHandle.cs delete mode 100644 src/DotNetty.NetUV/Native/NativeMethods.cs delete mode 100644 src/DotNetty.NetUV/Native/OperationException.cs delete mode 100644 src/DotNetty.NetUV/Native/Platform.cs delete mode 100644 src/DotNetty.NetUV/Properties/AssemblyInfo.cs delete mode 100644 src/DotNetty.NetUV/Properties/Friends.cs delete mode 100644 src/DotNetty.NetUV/readme.md rename src/DotNetty.Transport.Libuv/{LoopExecutor.cs => AbstractUVEventLoop.cs} (88%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Buffers/ReadableBuffer.cs (99%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Buffers/ReceiveBufferSizeEstimate.cs (99%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Buffers/WritableBuffer.cs (98%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Concurrency/Gate.cs (97%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Async.cs (76%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Check.cs (69%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/FSEvent.cs (91%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/FSPoll.cs (86%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/FileStatus.cs (95%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/HandleContext.cs (90%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/IReadCompletion.cs (94%) create mode 100644 src/DotNetty.Transport.Libuv/Handles/IScheduleHandle.cs create mode 100644 src/DotNetty.Transport.Libuv/Handles/IServerStream.cs rename src/{DotNetty.NetUV/Channels => DotNetty.Transport.Libuv/Handles}/IStreamConsumer.cs (85%) create mode 100644 src/DotNetty.Transport.Libuv/Handles/IStreamHandle.cs create mode 100644 src/DotNetty.Transport.Libuv/Handles/IWorkHandle.cs rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Idle.cs (69%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Loop.cs (80%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/LoopContext.cs (91%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Pipe.cs (57%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Pipeline.cs (83%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Poll.cs (83%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Prepare.cs (69%) rename src/{DotNetty.NetUV/Channels => DotNetty.Transport.Libuv/Handles}/ReadStreamConsumer.cs (76%) rename src/{DotNetty.NetUV/Handles/ScheduleHandle.cs => DotNetty.Transport.Libuv/Handles/ScheduleHandle (Of T).cs} (64%) rename src/{DotNetty.NetUV/Handles/ServerStream.cs => DotNetty.Transport.Libuv/Handles/ServerStream (Of T).cs} (54%) create mode 100644 src/DotNetty.Transport.Libuv/Handles/ServerStream.cs rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Signal.cs (82%) rename src/{DotNetty.NetUV/Channels => DotNetty.Transport.Libuv/Handles}/StreamConsumer.cs (76%) rename src/{DotNetty.NetUV/Handles/StreamHandle.cs => DotNetty.Transport.Libuv/Handles/StreamHandle (Of T).cs} (76%) create mode 100644 src/DotNetty.Transport.Libuv/Handles/StreamHandle.cs rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Tcp.cs (61%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Timer.cs (61%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Tty.cs (59%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Handles/Udp.cs (97%) rename src/{DotNetty.NetUV/Handles/WorkHandle.cs => DotNetty.Transport.Libuv/Handles/WorkHandle (Of T).cs} (53%) create mode 100644 src/DotNetty.Transport.Libuv/Handles/WorkHandle.cs rename src/DotNetty.Transport.Libuv/{Native/PlatformApi.Extensions.cs => INativeChannelUnsafe.cs} (58%) delete mode 100644 src/DotNetty.Transport.Libuv/Native/Async.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/Loop.cs rename src/{DotNetty.NetUV/Native/NativeFiles.cs => DotNetty.Transport.Libuv/Native/NativeMethods.Files.cs} (98%) rename src/{DotNetty.NetUV/Native/NativeHandles.cs => DotNetty.Transport.Libuv/Native/NativeMethods.Handles.cs} (87%) rename src/{DotNetty.NetUV/Native/NativeLoop.cs => DotNetty.Transport.Libuv/Native/NativeMethods.Loop.cs} (96%) rename src/{DotNetty.NetUV/Native/NativeRequests.cs => DotNetty.Transport.Libuv/Native/NativeMethods.Requests.cs} (98%) rename src/{DotNetty.NetUV/Native/NativeStreams.cs => DotNetty.Transport.Libuv/Native/NativeMethods.Streams.cs} (98%) delete mode 100644 src/DotNetty.Transport.Libuv/Native/NativeRequest.cs rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Native/PendingRead.cs (97%) delete mode 100644 src/DotNetty.Transport.Libuv/Native/Pipe.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/PipeHandle.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/PipeListener.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/PlatformApi.cs create mode 100644 src/DotNetty.Transport.Libuv/Native/PlatformApis.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/Tcp.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/TcpConnect.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/TcpHandle.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/TcpListener.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/Timer.cs delete mode 100644 src/DotNetty.Transport.Libuv/Native/WriteRequest.cs rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/AddressInfoRequest.cs (92%) rename src/DotNetty.Transport.Libuv/{Native => Requests}/ConnectRequest.cs (90%) rename src/{DotNetty.NetUV/Handles => DotNetty.Transport.Libuv/Requests}/HandleExtensions.cs (81%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/NameInfoRequest.cs (92%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/PipeConnect.cs (95%) create mode 100644 src/DotNetty.Transport.Libuv/Requests/PipeListener.cs rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/RequestContext.cs (89%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/ScheduleRequest.cs (94%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/StreamShutdown.cs (75%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/TcpConnect.cs (71%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/WatcherRequest.cs (82%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/Work.cs (92%) rename src/{DotNetty.NetUV => DotNetty.Transport.Libuv}/Requests/WriteRequest.cs (90%) rename src/DotNetty.Transport.Libuv/{EventLoop.cs => UVEventLoop.cs} (78%) rename src/DotNetty.Transport.Libuv/{EventLoopChooserFactory.cs => UVEventLoopChooserFactory.cs} (92%) rename src/DotNetty.Transport.Libuv/{EventLoopGroup.cs => UVEventLoopGroup.cs} (54%) delete mode 100644 src/DotNetty.Transport/Channels/Sockets/PlatformApis.cs delete mode 100644 test/DotNetty.NetUV.Tests.Netstandard/DotNetty.NetUV.Tests.csproj delete mode 100644 test/DotNetty.NetUV.Tests.Netstandard/run.netcore21.cmd delete mode 100644 test/DotNetty.NetUV.Tests.Netstandard/run.netcore31.cmd delete mode 100644 test/DotNetty.NetUV.Tests/DotNetty.NetUV.Tests.csproj delete mode 100644 test/DotNetty.NetUV.Tests/run.net452.cmd delete mode 100644 test/DotNetty.NetUV.Tests/run.net471.cmd delete mode 100644 test/DotNetty.NetUV.Tests/run.net5.cmd delete mode 100644 test/DotNetty.NetUV.Tests/run.netcore21.cmd delete mode 100644 test/DotNetty.NetUV.Tests/run.netcore31.cmd delete mode 100644 test/DotNetty.Transport.Libuv.Tests/AutoReadTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/BufReleaseTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/CloseForciblyTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/CompositeBufferGatheringWriteTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/ConnectTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/ConnectionAttemptTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/DetectPeerCloseWithoutReadTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/EchoTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/EventLoopTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/ExceptionHandlingTests.cs rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/ActiveTests.cs (94%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/AsyncTests.cs (94%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/CallbackOrderTests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/CloseOrderTests.cs (93%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/ConnectionFailTests.cs (96%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/FSEventTests.cs (98%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/FSPollTests.cs (96%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/GetAddrInfoTests.cs (94%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/GetNameInfoTests.cs (90%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/GetSockNameTests.cs (96%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/IdleTests.cs (91%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/LoopAliveTests.cs (92%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/LoopHandleTests.cs (98%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/LoopRunNoWaitTests.cs (90%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/LoopRunOnceTests.cs (92%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/LoopStopTests.cs (94%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/LoopTimeTests.cs (93%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/MultipleListenTests.cs (96%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PipeBindErrorTests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PipeConnectErrorTests.cs (91%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PipeConnectMultipleTests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PipeConnectPrepareTests.cs (89%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PipeGetSockNameTests.cs (93%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PipePendingInstancesTests.cs (91%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PipeServerCloseTests.cs (92%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PollCloseSocketTests.cs (94%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PollCloseTests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/PollTests.cs (98%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/RefTests.cs (87%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TcpBind6ErrorTests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TcpBindErrorTests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TcpCloseTests.cs (96%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TcpCloseWhileConnectingTests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TcpConnectTimeoutTests.cs (94%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TcpFlagsTests.cs (89%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TcpTryWriteTests.cs (96%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TestHelper.cs (99%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TimerTests.cs (98%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/TtyTests.cs (93%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpBindTests.cs (91%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpDatagramTooBigTests.cs (92%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpIPv6Tests.cs (85%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpMulticastInterface6Tests.cs (93%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpMulticastInterfaceTests.cs (94%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpMulticastJoin6Tests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpMulticastJoinTests.cs (96%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpMulticastTtlTests.cs (93%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpOptionsTests.cs (95%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpSendAndReceiveTests.cs (97%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpSendImmediateTests.cs (96%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpSendUnreachableTests.cs (90%) rename test/{DotNetty.NetUV.Tests => DotNetty.Transport.Libuv.Tests}/Handles/UdpTrySendTests.cs (93%) delete mode 100644 test/DotNetty.Transport.Libuv.Tests/ReadPendingTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/ResetTests.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/TestUtil.cs delete mode 100644 test/DotNetty.Transport.Libuv.Tests/WriteBeforeRegisteredTests.cs diff --git a/.gitignore b/.gitignore index 183abd9f7..f49ad4174 100644 --- a/.gitignore +++ b/.gitignore @@ -385,3 +385,4 @@ TODO.txt /test/DotNetty.Transport.Tests.Performance/Perf /tools /global.json +/src/DotNetty.Transport.Libuv/Kestrel diff --git a/DotNetty.CrossPlatform.sln b/DotNetty.CrossPlatform.sln index 76e84ef73..e80aa1452 100644 --- a/DotNetty.CrossPlatform.sln +++ b/DotNetty.CrossPlatform.sln @@ -37,8 +37,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Codecs.Mqtt", "src EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Codecs.Redis", "src\DotNetty.Codecs.Redis\DotNetty.Codecs.Redis.csproj", "{4ED4B313-21BA-473E-ADC0-FF36E64C2DCF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Transport.Libuv", "src\DotNetty.Transport.Libuv\DotNetty.Transport.Libuv.csproj", "{F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Codecs.Http", "src\DotNetty.Codecs.Http\DotNetty.Codecs.Http.csproj", "{87DD4EAA-BBCF-439F-A263-59044B6E8930}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Codecs.Http2", "src\DotNetty.Codecs.Http2\DotNetty.Codecs.Http2.csproj", "{85BC5580-3A11-4078-8DB7-3C113DA938A2}" @@ -54,8 +52,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "azure-pipelines", "azure-pi build\pr-validation.yaml = build\pr-validation.yaml EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.NetUV", "src\DotNetty.NetUV\DotNetty.NetUV.csproj", "{3162B002-96BD-4C3A-BA83-94791BA65A49}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "local-build", "local-build", "{D16D7F56-E54C-498D-B4B2-AEBF1C8CA462}" ProjectSection(SolutionItems) = preProject DotnetCLIVersion.txt = DotnetCLIVersion.txt @@ -66,6 +62,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "local-build", "local-build" localRestore.cmd = localRestore.cmd EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AD9FC79F-D6E7-4787-8E9E-604D92D996F9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Transport.Libuv", "src\DotNetty.Transport.Libuv\DotNetty.Transport.Libuv.csproj", "{63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Transport.Libuv.Tests", "test\DotNetty.Transport.Libuv.Tests\DotNetty.Transport.Libuv.Tests.csproj", "{A441B885-7764-4E67-9150-BDB1A594B130}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Tests.Common", "test\DotNetty.Tests.Common\DotNetty.Tests.Common.csproj", "{C48B5329-2735-45A7-9670-4FB13FCB6005}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -190,22 +194,6 @@ Global {4ED4B313-21BA-473E-ADC0-FF36E64C2DCF}.Release|x64.Build.0 = Release|Any CPU {4ED4B313-21BA-473E-ADC0-FF36E64C2DCF}.Release|x86.ActiveCfg = Release|Any CPU {4ED4B313-21BA-473E-ADC0-FF36E64C2DCF}.Release|x86.Build.0 = Release|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Debug|ARM.ActiveCfg = Debug|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Debug|ARM.Build.0 = Debug|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Debug|x64.ActiveCfg = Debug|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Debug|x64.Build.0 = Debug|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Debug|x86.ActiveCfg = Debug|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Debug|x86.Build.0 = Debug|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Release|Any CPU.Build.0 = Release|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Release|ARM.ActiveCfg = Release|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Release|ARM.Build.0 = Release|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Release|x64.ActiveCfg = Release|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Release|x64.Build.0 = Release|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Release|x86.ActiveCfg = Release|Any CPU - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5}.Release|x86.Build.0 = Release|Any CPU {87DD4EAA-BBCF-439F-A263-59044B6E8930}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {87DD4EAA-BBCF-439F-A263-59044B6E8930}.Debug|Any CPU.Build.0 = Debug|Any CPU {87DD4EAA-BBCF-439F-A263-59044B6E8930}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -270,22 +258,54 @@ Global {10264C0F-F854-4201-AFCB-2B7315EFBCE0}.Release|x64.Build.0 = Release|Any CPU {10264C0F-F854-4201-AFCB-2B7315EFBCE0}.Release|x86.ActiveCfg = Release|Any CPU {10264C0F-F854-4201-AFCB-2B7315EFBCE0}.Release|x86.Build.0 = Release|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|ARM.ActiveCfg = Debug|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|ARM.Build.0 = Debug|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|x64.ActiveCfg = Debug|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|x64.Build.0 = Debug|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|x86.ActiveCfg = Debug|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|x86.Build.0 = Debug|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|Any CPU.Build.0 = Release|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|ARM.ActiveCfg = Release|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|ARM.Build.0 = Release|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|x64.ActiveCfg = Release|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|x64.Build.0 = Release|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|x86.ActiveCfg = Release|Any CPU - {3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|x86.Build.0 = Release|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Debug|ARM.ActiveCfg = Debug|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Debug|ARM.Build.0 = Debug|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Debug|x64.ActiveCfg = Debug|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Debug|x64.Build.0 = Debug|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Debug|x86.ActiveCfg = Debug|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Debug|x86.Build.0 = Debug|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Release|Any CPU.Build.0 = Release|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Release|ARM.ActiveCfg = Release|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Release|ARM.Build.0 = Release|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Release|x64.ActiveCfg = Release|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Release|x64.Build.0 = Release|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Release|x86.ActiveCfg = Release|Any CPU + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1}.Release|x86.Build.0 = Release|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Debug|ARM.ActiveCfg = Debug|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Debug|ARM.Build.0 = Debug|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Debug|x64.ActiveCfg = Debug|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Debug|x64.Build.0 = Debug|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Debug|x86.ActiveCfg = Debug|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Debug|x86.Build.0 = Debug|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Release|Any CPU.Build.0 = Release|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Release|ARM.ActiveCfg = Release|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Release|ARM.Build.0 = Release|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Release|x64.ActiveCfg = Release|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Release|x64.Build.0 = Release|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Release|x86.ActiveCfg = Release|Any CPU + {A441B885-7764-4E67-9150-BDB1A594B130}.Release|x86.Build.0 = Release|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Debug|ARM.ActiveCfg = Debug|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Debug|ARM.Build.0 = Debug|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Debug|x64.ActiveCfg = Debug|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Debug|x64.Build.0 = Debug|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Debug|x86.ActiveCfg = Debug|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Debug|x86.Build.0 = Debug|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Release|Any CPU.Build.0 = Release|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Release|ARM.ActiveCfg = Release|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Release|ARM.Build.0 = Release|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Release|x64.ActiveCfg = Release|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Release|x64.Build.0 = Release|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Release|x86.ActiveCfg = Release|Any CPU + {C48B5329-2735-45A7-9670-4FB13FCB6005}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -298,14 +318,15 @@ Global {B4E683BC-92EA-4ADC-8B99-BA7208507D80} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} {D8AE3ECA-1BE6-44C5-9174-7C92CCFBEFC2} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} {4ED4B313-21BA-473E-ADC0-FF36E64C2DCF} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} - {F89EE43E-F0AE-4EA1-BEFF-6322C6E8EAF5} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} {87DD4EAA-BBCF-439F-A263-59044B6E8930} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} {85BC5580-3A11-4078-8DB7-3C113DA938A2} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} {F5A34D9C-854C-4972-ABF3-8BAE4712386D} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} {10264C0F-F854-4201-AFCB-2B7315EFBCE0} = {B6984E67-A4D0-459E-B3C9-01CA4DBBE241} {EC6681D3-3F9C-4CBB-B5D5-091E7F85D1C7} = {013DFD29-E1DB-4968-A67B-C2342E6F5B6E} - {3162B002-96BD-4C3A-BA83-94791BA65A49} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} {D16D7F56-E54C-498D-B4B2-AEBF1C8CA462} = {013DFD29-E1DB-4968-A67B-C2342E6F5B6E} + {63D2CCAD-AC78-4C95-A0EC-BC1AE855E9C1} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} + {A441B885-7764-4E67-9150-BDB1A594B130} = {AD9FC79F-D6E7-4787-8E9E-604D92D996F9} + {C48B5329-2735-45A7-9670-4FB13FCB6005} = {AD9FC79F-D6E7-4787-8E9E-604D92D996F9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A659CEFB-DDB3-49BE-AEDD-FF2F1B3297DB} diff --git a/DotNetty.Netstandard.sln b/DotNetty.Netstandard.sln index ee89d3ec5..f982ae97e 100644 --- a/DotNetty.Netstandard.sln +++ b/DotNetty.Netstandard.sln @@ -73,10 +73,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.End2End.Tests", "t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Suite.Tests", "test\DotNetty.Suite.Tests.Netstandard\DotNetty.Suite.Tests.csproj", "{D7063A5D-CEEE-4496-96E9-AA244B44744B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.NetUV.Netstandard", "src\DotNetty.NetUV\DotNetty.NetUV.Netstandard.csproj", "{70213847-9E6A-4880-8808-CE469A75D42D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.NetUV.Tests", "test\DotNetty.NetUV.Tests.Netstandard\DotNetty.NetUV.Tests.csproj", "{21FCDAD0-26FC-41E6-B385-DEAB88BD661B}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "azure-pipelines", "azure-pipelines", "{7AF386B8-794E-449E-9174-D6FD9ADD99EF}" ProjectSection(SolutionItems) = preProject build\azure-pipeline.template.yaml = build\azure-pipeline.template.yaml @@ -506,38 +502,6 @@ Global {D7063A5D-CEEE-4496-96E9-AA244B44744B}.Release|x64.Build.0 = Release|Any CPU {D7063A5D-CEEE-4496-96E9-AA244B44744B}.Release|x86.ActiveCfg = Release|Any CPU {D7063A5D-CEEE-4496-96E9-AA244B44744B}.Release|x86.Build.0 = Release|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Debug|ARM.ActiveCfg = Debug|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Debug|ARM.Build.0 = Debug|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Debug|x64.ActiveCfg = Debug|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Debug|x64.Build.0 = Debug|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Debug|x86.ActiveCfg = Debug|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Debug|x86.Build.0 = Debug|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Release|Any CPU.Build.0 = Release|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Release|ARM.ActiveCfg = Release|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Release|ARM.Build.0 = Release|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Release|x64.ActiveCfg = Release|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Release|x64.Build.0 = Release|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Release|x86.ActiveCfg = Release|Any CPU - {70213847-9E6A-4880-8808-CE469A75D42D}.Release|x86.Build.0 = Release|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Debug|ARM.ActiveCfg = Debug|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Debug|ARM.Build.0 = Debug|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Debug|x64.ActiveCfg = Debug|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Debug|x64.Build.0 = Debug|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Debug|x86.ActiveCfg = Debug|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Debug|x86.Build.0 = Debug|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Release|Any CPU.Build.0 = Release|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Release|ARM.ActiveCfg = Release|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Release|ARM.Build.0 = Release|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Release|x64.ActiveCfg = Release|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Release|x64.Build.0 = Release|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Release|x86.ActiveCfg = Release|Any CPU - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -568,8 +532,6 @@ Global {EE14EB67-04A4-45AE-91F0-0A0DB36D7C0B} = {2CCCD679-102A-4422-97D8-DA1A55DAFCA5} {37F48AC6-2A51-45AF-AEF0-1C83CB076B4E} = {2CCCD679-102A-4422-97D8-DA1A55DAFCA5} {D7063A5D-CEEE-4496-96E9-AA244B44744B} = {2CCCD679-102A-4422-97D8-DA1A55DAFCA5} - {70213847-9E6A-4880-8808-CE469A75D42D} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} - {21FCDAD0-26FC-41E6-B385-DEAB88BD661B} = {2CCCD679-102A-4422-97D8-DA1A55DAFCA5} {7AF386B8-794E-449E-9174-D6FD9ADD99EF} = {013DFD29-E1DB-4968-A67B-C2342E6F5B6E} {468C56AA-C2DC-4D2E-A5E3-92CF53703867} = {013DFD29-E1DB-4968-A67B-C2342E6F5B6E} EndGlobalSection diff --git a/DotNetty.sln b/DotNetty.sln index 74e3f8ea4..f5198ca62 100644 --- a/DotNetty.sln +++ b/DotNetty.sln @@ -82,10 +82,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.End2End.Tests", "t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Suite.Tests", "test\DotNetty.Suite.Tests\DotNetty.Suite.Tests.csproj", "{920F73C7-7FBE-44BE-8A99-3A394207D4C8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.NetUV", "src\DotNetty.NetUV\DotNetty.NetUV.csproj", "{68548ECD-222C-40C8-B975-46A17E5D5038}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.NetUV.Tests", "test\DotNetty.NetUV.Tests\DotNetty.NetUV.Tests.csproj", "{1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "local-build", "local-build", "{E27C94F8-A148-46D4-A1E0-2CC2B1FBECE9}" ProjectSection(SolutionItems) = preProject DotnetCLIVersion.txt = DotnetCLIVersion.txt @@ -524,38 +520,6 @@ Global {920F73C7-7FBE-44BE-8A99-3A394207D4C8}.Release|x64.Build.0 = Release|Any CPU {920F73C7-7FBE-44BE-8A99-3A394207D4C8}.Release|x86.ActiveCfg = Release|Any CPU {920F73C7-7FBE-44BE-8A99-3A394207D4C8}.Release|x86.Build.0 = Release|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Debug|Any CPU.Build.0 = Debug|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Debug|ARM.ActiveCfg = Debug|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Debug|ARM.Build.0 = Debug|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Debug|x64.ActiveCfg = Debug|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Debug|x64.Build.0 = Debug|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Debug|x86.ActiveCfg = Debug|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Debug|x86.Build.0 = Debug|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Release|Any CPU.ActiveCfg = Release|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Release|Any CPU.Build.0 = Release|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Release|ARM.ActiveCfg = Release|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Release|ARM.Build.0 = Release|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Release|x64.ActiveCfg = Release|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Release|x64.Build.0 = Release|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Release|x86.ActiveCfg = Release|Any CPU - {68548ECD-222C-40C8-B975-46A17E5D5038}.Release|x86.Build.0 = Release|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Debug|ARM.ActiveCfg = Debug|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Debug|ARM.Build.0 = Debug|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Debug|x64.ActiveCfg = Debug|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Debug|x64.Build.0 = Debug|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Debug|x86.ActiveCfg = Debug|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Debug|x86.Build.0 = Debug|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Release|Any CPU.Build.0 = Release|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Release|ARM.ActiveCfg = Release|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Release|ARM.Build.0 = Release|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Release|x64.ActiveCfg = Release|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Release|x64.Build.0 = Release|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Release|x86.ActiveCfg = Release|Any CPU - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -588,8 +552,6 @@ Global {A8473C9F-08FF-47DE-8C23-D2BAF5EF4E0A} = {013DFD29-E1DB-4968-A67B-C2342E6F5B6E} {E6B102FE-C706-4C40-B4F9-569EFC89B70F} = {01F3CC7E-F996-411E-AFD6-72673A826549} {920F73C7-7FBE-44BE-8A99-3A394207D4C8} = {01F3CC7E-F996-411E-AFD6-72673A826549} - {68548ECD-222C-40C8-B975-46A17E5D5038} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB} - {1C3FD988-6CBF-4EAE-A78D-F7D8BA085E0D} = {01F3CC7E-F996-411E-AFD6-72673A826549} {E27C94F8-A148-46D4-A1E0-2CC2B1FBECE9} = {013DFD29-E1DB-4968-A67B-C2342E6F5B6E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/DotNetty.Buffers/AbstractUnpooledSlicedByteBuffer.cs b/src/DotNetty.Buffers/AbstractUnpooledSlicedByteBuffer.cs index eef32e2d2..92b926a4e 100644 --- a/src/DotNetty.Buffers/AbstractUnpooledSlicedByteBuffer.cs +++ b/src/DotNetty.Buffers/AbstractUnpooledSlicedByteBuffer.cs @@ -51,7 +51,7 @@ protected AbstractUnpooledSlicedByteBuffer(IByteBuffer buffer, int index, int le _adjustment = byteBuffer._adjustment + index; break; - case UnpooledDuplicatedByteBuffer _: + case UnpooledDuplicatedByteBuffer: _buffer = (AbstractByteBuffer)buffer.Unwrap(); _adjustment = index; break; diff --git a/src/DotNetty.Buffers/ByteBufferUtil.Ascii.cs b/src/DotNetty.Buffers/ByteBufferUtil.Ascii.cs index 2c4a008ae..0d46e3a2c 100644 --- a/src/DotNetty.Buffers/ByteBufferUtil.Ascii.cs +++ b/src/DotNetty.Buffers/ByteBufferUtil.Ascii.cs @@ -58,7 +58,7 @@ public static int WriteAscii(IByteBuffer buf, ICharSequence seq) { switch (buf) { - case WrappedCompositeByteBuffer _: + case WrappedCompositeByteBuffer: // WrappedCompositeByteBuf is a sub-class of AbstractByteBuf so it needs special handling. buf = buf.Unwrap(); break; @@ -69,7 +69,7 @@ public static int WriteAscii(IByteBuffer buf, ICharSequence seq) _ = byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); return written; - case WrappedByteBuffer _: + case WrappedByteBuffer: // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. buf = buf.Unwrap(); break; @@ -100,7 +100,7 @@ public static int WriteAscii(IByteBuffer buf, string value) { switch (buf) { - case WrappedCompositeByteBuffer _: + case WrappedCompositeByteBuffer: // WrappedCompositeByteBuf is a sub-class of AbstractByteBuf so it needs special handling. buf = buf.Unwrap(); break; @@ -111,7 +111,7 @@ public static int WriteAscii(IByteBuffer buf, string value) _ = byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); return written; - case WrappedByteBuffer _: + case WrappedByteBuffer: // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. buf = buf.Unwrap(); break; diff --git a/src/DotNetty.Buffers/ByteBufferUtil.Utf8.cs b/src/DotNetty.Buffers/ByteBufferUtil.Utf8.cs index 5e49b34a9..9e84c07d4 100644 --- a/src/DotNetty.Buffers/ByteBufferUtil.Utf8.cs +++ b/src/DotNetty.Buffers/ByteBufferUtil.Utf8.cs @@ -99,7 +99,7 @@ private static int ReserveAndWriteUtf8Seq(IByteBuffer buf, ICharSequence seq, in { switch (buf) { - case WrappedCompositeByteBuffer _: + case WrappedCompositeByteBuffer: // WrappedCompositeByteBuf is a sub-class of AbstractByteBuf so it needs special handling. buf = buf.Unwrap(); break; @@ -110,7 +110,7 @@ private static int ReserveAndWriteUtf8Seq(IByteBuffer buf, ICharSequence seq, in byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); return written; - case WrappedByteBuffer _: + case WrappedByteBuffer: // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. buf = buf.Unwrap(); break; @@ -288,7 +288,7 @@ public static int ReserveAndWriteUtf8(IByteBuffer buf, in ReadOnlySpan cha { switch (buf) { - case WrappedCompositeByteBuffer _: + case WrappedCompositeByteBuffer: // WrappedCompositeByteBuf is a sub-class of AbstractByteBuf so it needs special handling. buf = buf.Unwrap(); break; @@ -299,7 +299,7 @@ public static int ReserveAndWriteUtf8(IByteBuffer buf, in ReadOnlySpan cha _ = byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); return written; - case WrappedByteBuffer _: + case WrappedByteBuffer: // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. buf = buf.Unwrap(); break; diff --git a/src/DotNetty.Buffers/CompositeByteBuffer.cs b/src/DotNetty.Buffers/CompositeByteBuffer.cs index cef3b5485..b0e1809e2 100644 --- a/src/DotNetty.Buffers/CompositeByteBuffer.cs +++ b/src/DotNetty.Buffers/CompositeByteBuffer.cs @@ -342,9 +342,9 @@ ComponentEntry NewComponent(IByteBuffer buf, int offset) unwrapped = unwrapped.Unwrap(); break; - case PooledDuplicatedByteBuffer _: - case ArrayPooledDuplicatedByteBuffer _: - case UnpooledDuplicatedByteBuffer _: + case PooledDuplicatedByteBuffer: + case ArrayPooledDuplicatedByteBuffer: + case UnpooledDuplicatedByteBuffer: unwrapped = unwrapped.Unwrap(); break; } diff --git a/src/DotNetty.Buffers/ReadOnlyByteBuffer.cs b/src/DotNetty.Buffers/ReadOnlyByteBuffer.cs index ecb3b75dc..3b5c7ee80 100644 --- a/src/DotNetty.Buffers/ReadOnlyByteBuffer.cs +++ b/src/DotNetty.Buffers/ReadOnlyByteBuffer.cs @@ -46,8 +46,8 @@ public ReadOnlyByteBuffer(IByteBuffer buffer) switch (buffer) { - case ReadOnlyByteBuffer _: - case UnpooledDuplicatedByteBuffer _: + case ReadOnlyByteBuffer: + case UnpooledDuplicatedByteBuffer: _buffer = buffer.Unwrap(); break; diff --git a/src/DotNetty.Buffers/UnpooledDuplicatedByteBuffer.cs b/src/DotNetty.Buffers/UnpooledDuplicatedByteBuffer.cs index 6b8beed29..0c226108c 100644 --- a/src/DotNetty.Buffers/UnpooledDuplicatedByteBuffer.cs +++ b/src/DotNetty.Buffers/UnpooledDuplicatedByteBuffer.cs @@ -50,11 +50,11 @@ internal UnpooledDuplicatedByteBuffer(AbstractByteBuffer buffer, int readerIndex _buffer = duplicated._buffer; break; - case AbstractPooledDerivedByteBuffer _: + case AbstractPooledDerivedByteBuffer: _buffer = (AbstractByteBuffer)buffer.Unwrap(); break; - case AbstractArrayPooledDerivedByteBuffer _: + case AbstractArrayPooledDerivedByteBuffer: _buffer = (AbstractByteBuffer)buffer.Unwrap(); break; diff --git a/src/DotNetty.Codecs.Http/HttpContentEncoder.cs b/src/DotNetty.Codecs.Http/HttpContentEncoder.cs index f498d592a..0de69eed7 100644 --- a/src/DotNetty.Codecs.Http/HttpContentEncoder.cs +++ b/src/DotNetty.Codecs.Http/HttpContentEncoder.cs @@ -60,8 +60,8 @@ public override bool AcceptOutboundMessage(object msg) { switch (msg) { - case IHttpContent _: - case IHttpResponse _: + case IHttpContent: + case IHttpResponse: return true; default: diff --git a/src/DotNetty.Codecs.Http/HttpObjectEncoder.cs b/src/DotNetty.Codecs.Http/HttpObjectEncoder.cs index dc6b73c69..f3dd89628 100644 --- a/src/DotNetty.Codecs.Http/HttpObjectEncoder.cs +++ b/src/DotNetty.Codecs.Http/HttpObjectEncoder.cs @@ -100,9 +100,9 @@ protected override void Encode(IChannelHandlerContext context, object message, L switch (message) { - case IHttpContent _: - case IByteBuffer _: - case IFileRegion _: + case IHttpContent: + case IByteBuffer: + case IFileRegion: switch (this.state) { case StInit: @@ -239,9 +239,9 @@ public override bool AcceptOutboundMessage(object msg) { switch (msg) { - case IHttpObject _: - case IByteBuffer _: - case IFileRegion _: + case IHttpObject: + case IByteBuffer: + case IFileRegion: return true; default: return false; diff --git a/src/DotNetty.Codecs.Http2/Http2FrameCodec.cs b/src/DotNetty.Codecs.Http2/Http2FrameCodec.cs index ab471b038..aaadacbd7 100644 --- a/src/DotNetty.Codecs.Http2/Http2FrameCodec.cs +++ b/src/DotNetty.Codecs.Http2/Http2FrameCodec.cs @@ -381,7 +381,7 @@ public override void Write(IChannelHandlerContext ctx, object msg, IPromise prom _ = Encoder.WritePingAsync(ctx, pingFrame.Ack, pingFrame.Content, promise); break; - case IHttp2SettingsAckFrame _: + case IHttp2SettingsAckFrame: // In the event of manual SETTINGS ACK is is assumed the encoder will apply the earliest received but not // yet ACKed settings. _ = Encoder.WriteSettingsAckAsync(ctx, promise); diff --git a/src/DotNetty.Codecs.Http2/Http2MultiplexHandler.cs b/src/DotNetty.Codecs.Http2/Http2MultiplexHandler.cs index 49008241b..7b8b5b01b 100644 --- a/src/DotNetty.Codecs.Http2/Http2MultiplexHandler.cs +++ b/src/DotNetty.Codecs.Http2/Http2MultiplexHandler.cs @@ -165,7 +165,7 @@ public override void ChannelRead(IChannelHandlerContext context, object msg) _parentReadInProgress = true; switch (msg) { - case IHttp2WindowUpdateFrame _: + case IHttp2WindowUpdateFrame: // We dont want to propagate update frames to the user return; diff --git a/src/DotNetty.Codecs.Http2/Http2StreamFrameToHttpObjectCodec.cs b/src/DotNetty.Codecs.Http2/Http2StreamFrameToHttpObjectCodec.cs index fc3970b13..cd7563d48 100644 --- a/src/DotNetty.Codecs.Http2/Http2StreamFrameToHttpObjectCodec.cs +++ b/src/DotNetty.Codecs.Http2/Http2StreamFrameToHttpObjectCodec.cs @@ -61,8 +61,8 @@ public Http2StreamFrameToHttpObjectCodec(bool isServer, bool validateHeaders) public override bool AcceptInboundMessage(object msg) => msg switch { - IHttp2HeadersFrame _ => true, - IHttp2DataFrame _ => true, + IHttp2HeadersFrame => true, + IHttp2DataFrame => true, _ => false, }; diff --git a/src/DotNetty.Codecs.Http2/InboundHttp2ToHttpAdapter.cs b/src/DotNetty.Codecs.Http2/InboundHttp2ToHttpAdapter.cs index 49dbe31f8..c2c0411e5 100644 --- a/src/DotNetty.Codecs.Http2/InboundHttp2ToHttpAdapter.cs +++ b/src/DotNetty.Codecs.Http2/InboundHttp2ToHttpAdapter.cs @@ -332,7 +332,7 @@ public bool MustSendImmediately(IFullHttpMessage msg) { case IFullHttpResponse response: return response.Status.CodeClass == HttpStatusClass.Informational; - case IFullHttpRequest _: + case IFullHttpRequest: return msg.Headers.Contains(HttpHeaderNames.Expect); default: return false; diff --git a/src/DotNetty.Codecs/DotNetty.Codecs.csproj b/src/DotNetty.Codecs/DotNetty.Codecs.csproj index f2d4d8ed9..d4d6733f8 100644 --- a/src/DotNetty.Codecs/DotNetty.Codecs.csproj +++ b/src/DotNetty.Codecs/DotNetty.Codecs.csproj @@ -21,9 +21,6 @@ - - - diff --git a/src/DotNetty.Common/DotNetty.Common.csproj b/src/DotNetty.Common/DotNetty.Common.csproj index 2db789b46..1775dadd8 100644 --- a/src/DotNetty.Common/DotNetty.Common.csproj +++ b/src/DotNetty.Common/DotNetty.Common.csproj @@ -26,6 +26,7 @@ + diff --git a/src/DotNetty.Common/Internal/Platform.cs b/src/DotNetty.Common/Internal/Platform.cs index c2b8c2e07..547ecc0ee 100644 --- a/src/DotNetty.Common/Internal/Platform.cs +++ b/src/DotNetty.Common/Internal/Platform.cs @@ -3,11 +3,35 @@ namespace DotNetty.Common { - using System; + using System.Net.Sockets; + using System.Runtime.InteropServices; using DotNetty.Common.Internal; public static class Platform { + public static readonly bool OSSupportsIPv6; + + public static readonly bool OSSupportsIPv4; + + public static readonly bool IsWindows; + + public static readonly bool IsLinux; + + public static readonly bool IsDarwin; + + public static readonly bool IsUnix; + + static Platform() + { + IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + IsDarwin = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + IsUnix = IsLinux || IsDarwin; + + OSSupportsIPv6 = Socket.OSSupportsIPv6; + OSSupportsIPv4 = Socket.OSSupportsIPv4; + } + public static int GetCurrentProcessId() => PlatformProvider.Platform.GetCurrentProcessId(); public static byte[] GetDefaultDeviceId() => PlatformProvider.Platform.GetDefaultDeviceId(); diff --git a/src/DotNetty.Common/Utilities/AsciiString.Helpers.cs b/src/DotNetty.Common/Utilities/AsciiString.Helpers.cs index 096396d28..c507a3141 100644 --- a/src/DotNetty.Common/Utilities/AsciiString.Helpers.cs +++ b/src/DotNetty.Common/Utilities/AsciiString.Helpers.cs @@ -116,7 +116,7 @@ public static int GetHashCode(ICharSequence value) case null: return 0; - case AsciiString _: + case AsciiString: return value.GetHashCode(); default: @@ -315,7 +315,7 @@ public static bool RegionMatchesAscii(ICharSequence cs, bool ignoreCase, int csS switch (cs) { - case StringCharSequence _ when !ignoreCase && seq is StringCharSequence: + case StringCharSequence when !ignoreCase && seq is StringCharSequence: //we don't call regionMatches from String for ignoreCase==true. It's a general purpose method, //which make complex comparison in case of ignoreCase==true, which is useless for ASCII-only strings. //To avoid applying this complex ignore-case comparison, we will use regionMatchesCharSequences diff --git a/src/DotNetty.Handlers/Common/ServerChannelRebindHandler.cs b/src/DotNetty.Handlers/Common/ServerChannelRebindHandler.cs index e21c273ac..f7b33bb82 100644 --- a/src/DotNetty.Handlers/Common/ServerChannelRebindHandler.cs +++ b/src/DotNetty.Handlers/Common/ServerChannelRebindHandler.cs @@ -1,80 +1,80 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ +///* +// * Copyright 2012 The Netty Project +// * +// * The Netty Project licenses this file to you under the Apache License, +// * version 2.0 (the "License"); you may not use this file except in compliance +// * with the License. You may obtain a copy of the License at: +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// * License for the specific language governing permissions and limitations +// * under the License. +// * +// * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. +// * +// * https://github.com/cuteant/dotnetty-span-fork +// * +// * Licensed under the MIT license. See LICENSE file in the project root for full license information. +// */ -namespace DotNetty.Handlers -{ - using System; - using System.Net.Sockets; - using System.Threading.Tasks; - using DotNetty.Common.Internal.Logging; - using DotNetty.Transport.Channels; - using DotNetty.Transport.Channels.Sockets; - using DotNetty.Transport.Libuv.Native; +//namespace DotNetty.Handlers +//{ +// using System; +// using System.Net.Sockets; +// using System.Threading.Tasks; +// using DotNetty.Common.Internal.Logging; +// using DotNetty.Transport.Channels; +// using DotNetty.Transport.Channels.Sockets; +// using DotNetty.Transport.Libuv.Native; - public sealed class ServerChannelRebindHandler : ChannelHandlerAdapter - { - private readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); +// public sealed class ServerChannelRebindHandler : ChannelHandlerAdapter +// { +// private readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); - private readonly Action _doBindAction; - private readonly int _delaySeconds; +// private readonly Action _doBindAction; +// private readonly int _delaySeconds; - public ServerChannelRebindHandler(Action doBindAction) : this(doBindAction, 2) { } +// public ServerChannelRebindHandler(Action doBindAction) : this(doBindAction, 2) { } - public ServerChannelRebindHandler(Action doBindAction, int delaySeconds) - { - if (doBindAction is null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.doBindAction); - if (delaySeconds <= 0) { delaySeconds = 2; } +// public ServerChannelRebindHandler(Action doBindAction, int delaySeconds) +// { +// if (doBindAction is null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.doBindAction); +// if (delaySeconds <= 0) { delaySeconds = 2; } - _doBindAction = doBindAction; - _delaySeconds = delaySeconds; - } +// _doBindAction = doBindAction; +// _delaySeconds = delaySeconds; +// } - /// - public override bool IsSharable => true; +// /// +// public override bool IsSharable => true; - public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) - { - if (Logger.WarnEnabled) - { - Logger.Warn($"Channel {context.Channel} caught exception", exception); - } - switch (exception) - { - case SocketException se when se.SocketErrorCode.IsSocketAbortError(): - case OperationException oe when oe.ErrorCode.IsConnectionAbortError(): - case ChannelException ce when (ce.InnerException is OperationException exc && exc.ErrorCode.IsConnectionAbortError()): - DoBind(); - break; +// public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) +// { +// if (Logger.WarnEnabled) +// { +// Logger.Warn($"Channel {context.Channel} caught exception", exception); +// } +// switch (exception) +// { +// case SocketException se when se.SocketErrorCode.IsSocketAbortError(): +// case OperationException oe when oe.ErrorCode.IsConnectionAbortError(): +// case ChannelException ce when (ce.InnerException is OperationException exc && exc.ErrorCode.IsConnectionAbortError()): +// DoBind(); +// break; - default: - context.FireExceptionCaught(exception); - break; - } - } +// default: +// context.FireExceptionCaught(exception); +// break; +// } +// } - private async void DoBind() - { - await Task.Delay(TimeSpan.FromSeconds(_delaySeconds)); - _doBindAction(); - } - } -} +// private async void DoBind() +// { +// await Task.Delay(TimeSpan.FromSeconds(_delaySeconds)); +// _doBindAction(); +// } +// } +//} diff --git a/src/DotNetty.Handlers/DotNetty.Handlers.csproj b/src/DotNetty.Handlers/DotNetty.Handlers.csproj index 2809757ad..38b86b9dd 100644 --- a/src/DotNetty.Handlers/DotNetty.Handlers.csproj +++ b/src/DotNetty.Handlers/DotNetty.Handlers.csproj @@ -17,7 +17,6 @@ - diff --git a/src/DotNetty.NetUV/DotNetty.NetUV.Netstandard.csproj b/src/DotNetty.NetUV/DotNetty.NetUV.Netstandard.csproj deleted file mode 100644 index eac2d9115..000000000 --- a/src/DotNetty.NetUV/DotNetty.NetUV.Netstandard.csproj +++ /dev/null @@ -1,41 +0,0 @@ - - - - - netstandard2.0 - DotNetty.NetUV - SpanNetty.NetUV - true - - - - SpanNetty.NetUV - SpanNetty.NetUV - Libuv .NET/Core binding: the port of the NetUV.Core assembly to support .NET 4.5.1 and newer. - socket;tcp;utp;protocol;netty;dotnetty;network;libuv - - - - - - - - - - - - - True - True - Strings.resx - - - - - ResXFileCodeGenerator - Strings.Designer.cs - - - - - \ No newline at end of file diff --git a/src/DotNetty.NetUV/DotNetty.NetUV.csproj b/src/DotNetty.NetUV/DotNetty.NetUV.csproj deleted file mode 100644 index cab181ab2..000000000 --- a/src/DotNetty.NetUV/DotNetty.NetUV.csproj +++ /dev/null @@ -1,44 +0,0 @@ - - - - - $(StandardTfms) - DotNetty.NetUV - SpanNetty.NetUV - true - - - - SpanNetty.NetUV - SpanNetty.NetUV - Libuv .NET/Core binding: the port of the NetUV.Core assembly to support .NET 4.5.1 and newer. - socket;tcp;utp;protocol;netty;dotnetty;network;libuv - - - - - - - - - - - - - - - - True - True - Strings.resx - - - - - ResXFileCodeGenerator - Strings.Designer.cs - - - - - \ No newline at end of file diff --git a/src/DotNetty.NetUV/Internal/LoggingExtensions.cs b/src/DotNetty.NetUV/Internal/LoggingExtensions.cs deleted file mode 100644 index 7f383f4b4..000000000 --- a/src/DotNetty.NetUV/Internal/LoggingExtensions.cs +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -using System; -using System.Runtime.CompilerServices; -using DotNetty.Buffers; -using DotNetty.Common.Internal.Logging; -using DotNetty.NetUV.Handles; -using DotNetty.NetUV.Native; -using DotNetty.NetUV.Requests; - -namespace DotNetty.NetUV -{ - internal static class LibuvLoggingExtensions - { - #region -- Info -- - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void HandleAllocated(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle) - { - logger.Info("{} {} allocated.", handleType, handle); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void HandleClosedReleasingResourcesPending(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle) - { - logger.Info("{} {} closed, releasing resources pending.", handleType, handle); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopWalkCallbackDisposed(this IInternalLogger logger, IntPtr loopHandle, IntPtr handle, IDisposable target) - { - logger.Info($"Loop {loopHandle} walk callback disposed {handle} {target?.GetType()}"); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Loop_memory_released(this IInternalLogger logger, IntPtr handle) - { - logger.Info($"Loop {handle} memory released."); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Loop_GCHandle_released(this IInternalLogger logger, IntPtr handle) - { - logger.Info($"Loop {handle} GCHandle released."); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Loop_closed(this IInternalLogger logger, IntPtr handle) - { - logger.Info($"Loop {handle} closed."); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Loop_allocated(this IInternalLogger logger, IntPtr handle) - { - logger.Info($"Loop {handle} allocated."); - } - - #endregion - - #region -- Warn -- - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Handle_receive_result_truncated(this IInternalLogger logger, IntPtr handle, IByteBuffer byteBuffer) - { - logger.Warn($"{uv_handle_type.UV_UDP} {handle} receive result truncated, buffer size = {byteBuffer.Capacity}"); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Udp_Exception_whilst_invoking_read_callback(this IInternalLogger logger, Exception exception) - { - logger.Warn($"{nameof(Udp)} Exception whilst invoking read callback.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Failed_to_close_and_releasing_resources(this IInternalLogger logger, HandleContext handle, Exception exception) - { - logger.Warn($"{handle} Failed to close and releasing resources.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Failed_to_get_loop(this IInternalLogger logger, uv_handle_type handleType, Exception exception) - { - logger.Warn($"{handleType} Failed to get loop.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Pipeline_Exception_whilst_invoking_read_callback(this IInternalLogger logger, Exception exception) - { - logger.Warn($"{nameof(Pipeline)} Exception whilst invoking read callback.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Loop_Walk_callback_attempt_to_close_handle_failed(this IInternalLogger logger, IntPtr loopHandle, IntPtr handle, Exception exception) - { - logger.Warn($"Loop {loopHandle} Walk callback attempt to close handle {handle} failed.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Loop_close_all_handles_limit_20_times_exceeded(this IInternalLogger logger, IntPtr handle) - { - logger.Warn($"Loop {handle} close all handles limit 20 times exceeded."); - } - - #endregion - - #region -- Error -- - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void RequestType_after_callback_error(this IInternalLogger logger, uv_req_type requestType, Exception exception) - { - logger.Error($"{requestType} after callback error", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void RequestType_work_callback_error(this IInternalLogger logger, uv_req_type requestType, Exception exception) - { - logger.Error($"{requestType} work callback error", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void RequestType_OnWatcherCallback_error(this IInternalLogger logger, uv_req_type requestType, Exception exception) - { - logger.Error($"{requestType} OnWatcherCallback error.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void RequestType_OnWatcherCallback_error(this IInternalLogger logger, uv_req_type requestType, IntPtr handle, OperationException error) - { - logger.Error($"{requestType} {handle} error : {error.ErrorCode} {error.Name}.", error); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void UV_SHUTDOWN_callback_error(this IInternalLogger logger, Exception exception) - { - logger.Error("UV_SHUTDOWN callback error.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void NativeHandle_error_whilst_closing_handle(this IInternalLogger logger, IntPtr handle, Exception exception) - { - logger.Error($"{nameof(NativeHandle)} {handle} error whilst closing handle.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Handle_callback_error(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle, Exception exception) - { - logger.Error($"{handleType} {handle} callback error.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Handle_read_error(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle, int status, Exception exception) - { - logger.Error($"{handleType} {handle} read error, status = {status}", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Handle_faulted(this IInternalLogger logger, uv_handle_type handleType, Exception exception) - { - logger.Error($"{handleType} faulted.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Pipeline_Handle_faulted(this IInternalLogger logger, uv_handle_type handleType, Exception exception) - { - logger.Error($"{nameof(Pipeline)} {handleType} faulted.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Handle_close_handle_callback_error(this IInternalLogger logger, uv_handle_type handleType, Exception exception) - { - logger.Error($"{handleType} close handle callback error.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Failed_to_close_handle(this IInternalLogger logger, uv_handle_type handleType, Exception exception) - { - logger.Error($"{handleType} Failed to close handle.", exception); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Handle_failed_to_shutdown(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle, Exception error) - { - logger.Error($"{handleType} {handle} failed to shutdown.", error); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Failed_to_write_data(this IInternalLogger logger, uv_handle_type handleType, WriteRequest request, Exception exception) - { - logger.Error($"{handleType} Failed to write data {request}.", exception); - } - - #endregion - } -} diff --git a/src/DotNetty.NetUV/Internal/SR.cs b/src/DotNetty.NetUV/Internal/SR.cs deleted file mode 100644 index 74bcf6222..000000000 --- a/src/DotNetty.NetUV/Internal/SR.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -using System; -using System.Resources; - -namespace DotNetty.NetUV.Internal -{ - internal sealed partial class SR : Strings - { - // Needed for debugger integration - internal static string GetResourceString(string resourceKey) - { - return GetResourceString(resourceKey, String.Empty); - } - - internal static string GetResourceString(string resourceKey, string defaultString) - { - string resourceString = null; - try { resourceString = ResourceManager.GetString(resourceKey, null); } - catch (MissingManifestResourceException) { } - - if (defaultString is object && resourceKey.Equals(resourceString, StringComparison.Ordinal)) - { - return defaultString; - } - - return resourceString; - } - - internal static string Format(string resourceFormat, params object[] args) - { - if (args is object) - { - return String.Format(resourceFormat, args); - } - - return resourceFormat; - } - - internal static string Format(string resourceFormat, object p1) - { - return String.Format(resourceFormat, p1); - } - - internal static string Format(string resourceFormat, object p1, object p2) - { - return String.Format(resourceFormat, p1, p2); - } - - internal static string Format(string resourceFormat, object p1, object p2, object p3) - { - return String.Format(resourceFormat, p1, p2, p3); - } - } -} diff --git a/src/DotNetty.NetUV/Internal/Strings.Designer.cs b/src/DotNetty.NetUV/Internal/Strings.Designer.cs deleted file mode 100644 index 95ce3687c..000000000 --- a/src/DotNetty.NetUV/Internal/Strings.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 -// -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 -// -//------------------------------------------------------------------------------ - -namespace DotNetty.NetUV.Internal { - using System; - - - /// - /// 一个强类型的资源类,用于查找本地化的字符串等。 - /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Strings { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Strings() { - } - - /// - /// 返回此类使用的缓存的 ResourceManager 实例。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetty.NetUV.Internal.Strings", typeof(Strings).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// 重写当前线程的 CurrentUICulture 属性 - /// 重写当前线程的 CurrentUICulture 属性。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/src/DotNetty.NetUV/Internal/Strings.resx b/src/DotNetty.NetUV/Internal/Strings.resx deleted file mode 100644 index 1af7de150..000000000 --- a/src/DotNetty.NetUV/Internal/Strings.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/DotNetty.NetUV/Internal/ThrowHelper.Extensions.cs b/src/DotNetty.NetUV/Internal/ThrowHelper.Extensions.cs deleted file mode 100644 index fff99dab5..000000000 --- a/src/DotNetty.NetUV/Internal/ThrowHelper.Extensions.cs +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -using System; -using System.Net; -using System.Runtime.CompilerServices; -using DotNetty.NetUV.Handles; -using DotNetty.NetUV.Native; - -namespace DotNetty.NetUV -{ - #region -- ExceptionArgument -- - - /// The convention for this enum is using the argument name as the enum name - internal enum ExceptionArgument - { - s, - - pi, - fi, - ts, - - asm, - key, - obj, - str, - tcp, - udp, - - list, - pool, - name, - path, - item, - type, - func, - loop, - pipe, - size, - node, - task, - - match, - array, - other, - inner, - types, - value, - index, - count, - - action, - policy, - handle, - repeat, - offset, - method, - buffer, - source, - values, - parent, - length, - onRead, - socket, - target, - member, - - buffers, - backlog, - feature, - manager, - newSize, - invoker, - options, - minimum, - initial, - maximum, - onError, - service, - timeout, - - assembly, - capacity, - endPoint, - fullName, - typeInfo, - typeName, - nThreads, - onAccept, - callback, - interval, - - allocator, - defaultFn, - fieldInfo, - predicate, - - memberInfo, - returnType, - collection, - expression, - startIndex, - remoteName, - readAction, - completion, - sendHandle, - - directories, - dirEnumArgs, - destination, - - valueFactory, - propertyInfo, - instanceType, - workCallback, - streamHandle, - onConnection, - - attributeType, - localEndPoint, - receiveAction, - - chooserFactory, - eventLoopGroup, - parameterTypes, - remoteEndPoint, - - connectedAction, - - multicastAddress, - interfaceAddress, - - assemblyPredicate, - qualifiedTypeName, - - includedAssemblies, - } - - #endregion - - #region -- ExceptionResource -- - - /// The convention for this enum is using the resource name as the enum name - internal enum ExceptionResource - { - } - - #endregion - - internal partial class ThrowHelper - { - #region -- ArgumentException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException_Positive(int value, ExceptionArgument argument) - { - throw GetException(); - ArgumentException GetException() - { - return new ArgumentException($"{GetArgumentName(argument)}: {value} (expected: > 0)"); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException_Positive(long value, ExceptionArgument argument) - { - throw GetException(); - ArgumentException GetException() - { - return new ArgumentException($"{GetArgumentName(argument)}: {value} (expected: > 0)"); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException_PositiveOrZero(int value, ExceptionArgument argument) - { - throw GetException(); - ArgumentException GetException() - { - return new ArgumentException($"{GetArgumentName(argument)}: {value} (expected: >= 0)"); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException_PositiveOrZero(long value, ExceptionArgument argument) - { - throw GetException(); - ArgumentException GetException() - { - return new ArgumentException($"{GetArgumentName(argument)}: {value} (expected: >= 0)"); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static int ThrowArgumentException_PositiveOrOne(int value, ExceptionArgument argument) - { - throw GetException(); - ArgumentException GetException() - { - return new ArgumentException($"{GetArgumentName(argument)}: {value} (expected: >= 1)"); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException_InvalidOffLen() - { - throw GetException(); - static ArgumentException GetException() - { - return new ArgumentException("Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException_TtyMode_is_Unix_only(TtyMode mode) - { - throw GetException(); - ArgumentException GetException() - { - return new ArgumentException($"{mode} is Unix only.", nameof(mode)); - } - } - - #endregion - - #region -- InvalidOperationException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static InvalidOperationException GetInvalidOperationException_uv_handle_type_not_supported_or_IPC_over_Pipe_is_disabled(uv_handle_type handleType) - { - return new InvalidOperationException($"{handleType} not supported or IPC over Pipe is disabled."); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static InvalidOperationException GetInvalidOperationException_Pipe_IPC_handle_not_supported(uv_handle_type type) - { - return new InvalidOperationException($"Pipe IPC handle {type} not supported"); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_Udp_data_handler_has_already_been_registered() - { - throw GetException(); - static InvalidOperationException GetException() - { - return new InvalidOperationException( - $"{nameof(Udp)} data handler has already been registered"); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_uv_handle_type_is_not_readable(uv_handle_type handleType, IntPtr internalHandle, TtyType ttyType) - { - throw GetException(); - InvalidOperationException GetException() - { - return new InvalidOperationException( - $"{handleType} {internalHandle} mode {ttyType} is not readable"); - } - } - - #endregion - - #region -- NotSupportedException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static NotSupportedException GetNotSupportedException_Poll_argument_must_be_either_IntPtr_or_int() - { - return new NotSupportedException("Poll argument must be either IntPtr or int"); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static NotSupportedException GetNotSupportedException_expecting_InterNetworkkV6OrV4(IPEndPoint endPoint) - { - return new NotSupportedException( - $"End point {endPoint} is not supported, expecting InterNetwork/InterNetworkV6."); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static NotSupportedException GetNotSupportedException_Handle_type_to_initialize_not_supported(uv_handle_type handleType) - { - return new NotSupportedException($"Handle type to initialize {handleType} not supported"); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static NotSupportedException GetNotSupportedException_Handle_type_to_start_not_supported(uv_handle_type handleType) - { - return new NotSupportedException($"Handle type to start {handleType} not supported"); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static NotSupportedException GetNotSupportedException_Handle_type_to_stop_not_supported(uv_handle_type handleType) - { - return new NotSupportedException($"Handle type to stop {handleType} not supported"); - } - - #endregion - - #region -- PlatformNotSupportedException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowPlatformNotSupportedException_handle_type_send_buffer_size_setting_not_supported_on_Windows(uv_handle_type handleType) - { - throw GetException(); - PlatformNotSupportedException GetException() - { - return new PlatformNotSupportedException($"{handleType} send buffer size setting not supported on Windows"); - } - } - - #endregion - } -} diff --git a/src/DotNetty.NetUV/Internal/ThrowHelper.cs b/src/DotNetty.NetUV/Internal/ThrowHelper.cs deleted file mode 100644 index 1c764cfcd..000000000 --- a/src/DotNetty.NetUV/Internal/ThrowHelper.cs +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -using System; -using System.Runtime.CompilerServices; -using System.Diagnostics; -using DotNetty.NetUV.Internal; - -namespace DotNetty.NetUV -{ - internal static partial class ThrowHelper - { - #region -- Throw ArgumentException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException() - { - throw GetArgumentException(); - - static ArgumentException GetArgumentException() - { - return new ArgumentException(); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException(ExceptionResource resource) - { - throw GetArgumentException(resource); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException(ExceptionResource resource, ExceptionArgument argument) - { - throw GetArgumentException(resource, argument); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException(string message, ExceptionArgument argument) - { - throw GetArgumentException(); - ArgumentException GetArgumentException() - { - return new ArgumentException(message, GetArgumentName(argument)); - - } - } - - #endregion - - #region -- Get ArgumentException -- - - internal static ArgumentException GetArgumentException(ExceptionResource resource) - { - return new ArgumentException(GetResourceString(resource)); - } - - internal static ArgumentException GetArgumentException(ExceptionResource resource, ExceptionArgument argument) - { - return new ArgumentException(GetResourceString(resource), GetArgumentName(argument)); - } - - #endregion - - - #region -- Throw ArgumentOutOfRangeException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentOutOfRangeException() - { - throw GetArgumentOutOfRangeException(); - - static ArgumentOutOfRangeException GetArgumentOutOfRangeException() - { - return new ArgumentOutOfRangeException(); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument) - { - throw GetArgumentOutOfRangeException(argument); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) - { - throw GetArgumentOutOfRangeException(argument, resource); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource) - { - throw GetArgumentOutOfRangeException(argument, paramNumber, resource); - } - - #endregion - - #region -- Get ArgumentOutOfRangeException -- - - internal static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument) - { - return new ArgumentOutOfRangeException(GetArgumentName(argument)); - } - - internal static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) - { - return new ArgumentOutOfRangeException(GetArgumentName(argument), GetResourceString(resource)); - } - - internal static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource) - { - return new ArgumentOutOfRangeException(GetArgumentName(argument) + "[" + paramNumber.ToString() + "]", GetResourceString(resource)); - } - - #endregion - - - #region -- Throw ArgumentNullException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentNullException(ExceptionArgument argument) - { - throw GetArgumentNullException(argument); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentNullException(ExceptionResource resource) - { - throw GetArgumentNullException(resource); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentNullException(ExceptionArgument argument, ExceptionResource resource) - { - throw GetArgumentNullException(argument, resource); - } - - #endregion - - #region -- Get ArgumentNullException -- - - internal static ArgumentNullException GetArgumentNullException(ExceptionArgument argument) - { - return new ArgumentNullException(GetArgumentName(argument)); - } - - internal static ArgumentNullException GetArgumentNullException(ExceptionResource resource) - { - return new ArgumentNullException(GetResourceString(resource), innerException: null); - } - - internal static ArgumentNullException GetArgumentNullException(ExceptionArgument argument, ExceptionResource resource) - { - return new ArgumentNullException(GetArgumentName(argument), GetResourceString(resource)); - } - - #endregion - - - #region -- IndexOutOfRangeException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowIndexOutOfRangeException() - { - throw GetIndexOutOfRangeException(); - - static IndexOutOfRangeException GetIndexOutOfRangeException() - { - return new IndexOutOfRangeException(); - } - } - - #endregion - - #region -- Throw InvalidOperationException -- - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException(ExceptionResource resource) - { - throw GetInvalidOperationException(resource); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException(ExceptionResource resource, Exception e) - { - throw GetInvalidOperationException(); - InvalidOperationException GetInvalidOperationException() - { - return new InvalidOperationException(GetResourceString(resource), e); - } - } - - internal static InvalidOperationException GetInvalidOperationException(ExceptionResource resource) - { - return new InvalidOperationException(GetResourceString(resource)); - } - - #endregion - - #region ** GetArgumentName ** - - [MethodImpl(MethodImplOptions.NoInlining)] - private static string GetArgumentName(ExceptionArgument argument) - { - Debug.Assert(Enum.IsDefined(typeof(ExceptionArgument), argument), - "The enum value is not defined, please check the ExceptionArgument Enum."); - - return argument.ToString(); - } - - #endregion - - #region ** GetResourceString ** - - // This function will convert an ExceptionResource enum value to the resource string. - [MethodImpl(MethodImplOptions.NoInlining)] - private static string GetResourceString(ExceptionResource resource) - { - Debug.Assert(Enum.IsDefined(typeof(ExceptionResource), resource), - "The enum value is not defined, please check the ExceptionResource Enum."); - - return SR.GetResourceString(resource.ToString()); - } - - #endregion - } -} diff --git a/src/DotNetty.NetUV/Native/ErrorCode.cs b/src/DotNetty.NetUV/Native/ErrorCode.cs deleted file mode 100644 index 94ba47f45..000000000 --- a/src/DotNetty.NetUV/Native/ErrorCode.cs +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) Johnny Z. All rights reserved. - * - * https://github.com/StormHub/NetUV - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.NetUV.Native -{ - /// Reference: http://docs.libuv.org/en/v1.x/errors.html - public enum ErrorCode - { - /// UV_E2BIG: argument list too long - E2BIG, - - /// UV_EACCES: permission denied - EACCES, - - /// UV_EADDRINUSE: address already in use - EADDRINUSE, - - /// UV_EADDRNOTAVAIL: address not available - EADDRNOTAVAIL, - - /// UV_EAFNOSUPPORT: address family not supported - EAFNOSUPPORT, - - /// UV_EAGAIN: resource temporarily unavailable - EAGAIN, - - /// UV_EAI_ADDRFAMILY: address family not supported - EAI_ADDRFAMILY, - - /// UV_EAI_AGAIN: temporary failure - EAI_AGAIN, - - /// UV_EAI_BADFLAGS: bad ai_flags value - EAI_BADFLAGS, - - /// UV_EAI_BADHINTS: invalid value for hints - EAI_BADHINTS, - - /// UV_EAI_CANCELED: request canceled - EAI_CANCELED, - - /// UV_EAI_FAIL: permanent failure - EAI_FAIL, - - /// UV_EAI_FAMILY: ai_family not supported - EAI_FAMILY, - - /// UV_EAI_MEMORY: out of memory - EAI_MEMORY, - - /// UV_EAI_NODATA: no address - EAI_NODATA, - - /// UV_EAI_NONAME: unknown node or service - EAI_NONAME, - - /// UV_EAI_OVERFLOW: argument buffer overflow - EAI_OVERFLOW, - - /// UV_EAI_PROTOCOL: resolved protocol is unknown - EAI_PROTOCOL, - - /// UV_EAI_SERVICE: service not available for socket type - EAI_SERVICE, - - /// UV_EAI_SOCKTYPE: socket type not supported - EAI_SOCKTYPE, - - /// UV_EALREADY: connection already in progress - EALREADY, - - /// UV_EBADF: bad file descriptor - EBADF, - - /// UV_EBUSY: resource busy or locked - EBUSY, - - /// UV_ECANCELED: operation canceled - ECANCELED, - - /// UV_ECHARSET: invalid Unicode character - ECHARSET, - - /// UV_ECONNABORTED: software caused connection abort - ECONNABORTED, - - /// UV_ECONNREFUSED: connection refused - ECONNREFUSED, - - /// UV_ECONNRESET: connection reset by peer - ECONNRESET, - - /// UV_EDESTADDRREQ: destination address required - EDESTADDRREQ, - - /// UV_EEXIST: file already exists - EEXIST, - - /// UV_EFAULT: bad address in system call argument - EFAULT, - - /// UV_EFBIG: file too large - EFBIG, - - /// UV_EHOSTUNREACH: host is unreachable - EHOSTUNREACH, - - /// UV_EINTR: interrupted system call - EINTR, - - /// UV_EINVAL: invalid argument - EINVAL, - - /// UV_EIO: i/o error - EIO, - - /// UV_EISCONN: socket is already connected - EISCONN, - - /// UV_EISDIR: illegal operation on a directory - EISDIR, - - /// UV_ELOOP: too many symbolic links encountered - ELOOP, - - /// UV_EMFILE: too many open files - EMFILE, - - /// UV_EMSGSIZE: message too long - EMSGSIZE, - - /// UV_ENAMETOOLONG: name too long - ENAMETOOLONG, - - /// UV_ENETDOWN: network is down - ENETDOWN, - - /// UV_ENETUNREACH: network is unreachable - ENETUNREACH, - - /// UV_ENFILE: file table overflow - ENFILE, - - /// UV_ENOBUFS: no buffer space available - ENOBUFS, - - /// UV_ENODEV: no such device - ENODEV, - - /// UV_ENOENT: no such file or directory - ENOENT, - - /// UV_ENOMEM: not enough memory - ENOMEM, - - /// UV_ENONET: machine is not on the network - ENONET, - - /// UV_ENOPROTOOPT: protocol not available - ENOPROTOOPT, - - /// UV_ENOSPC: no space left on device - ENOSPC, - - /// UV_ENOSYS: function not implemented - ENOSYS, - - /// UV_ENOTCONN: socket is not connected - ENOTCONN, - - /// UV_ENOTDIR: not a directory - ENOTDIR, - - /// UV_ENOTEMPTY: directory not empty - ENOTEMPTY, - - /// UV_ENOTSOCK: socket operation on non-socket - ENOTSOCK, - - /// UV_ENOTSUP: operation not supported on socket - ENOTSUP, - - /// UV_EPERM: operation not permitted - EPERM, - - /// UV_EPIPE: broken pipe - EPIPE, - - /// UV_EPROTO: protocol error - EPROTO, - - /// UV_EPROTONOSUPPORT: protocol not supported - EPROTONOSUPPORT, - - /// UV_EPROTOTYPE: protocol wrong type for socket - EPROTOTYPE, - - /// UV_ERANGE: result too large - ERANGE, - - /// UV_EROFS: read-only file system - EROFS, - - /// UV_ESHUTDOWN: cannot send after transport endpoint shutdown - ESHUTDOWN, - - /// UV_ESPIPE: invalid seek - ESPIPE, - - /// UV_ESRCH: no such process - ESRCH, - - /// UV_ETIMEDOUT: connection timed out - ETIMEDOUT, - - /// UV_ETXTBSY: text file is busy - ETXTBSY, - - /// UV_EXDEV: cross-device link not permitted - EXDEV, - - /// UV_UNKNOWN: unknown error - UNKNOWN, - - /// UV_EOF: end of file - EOF, - - /// UV_ENXIO: no such device or address - ENXIO, - - /// UV_EMLINK: too many links - EMLINK, - } -} diff --git a/src/DotNetty.NetUV/Native/ErrorCodeExtensions.cs b/src/DotNetty.NetUV/Native/ErrorCodeExtensions.cs deleted file mode 100644 index 71d8f9981..000000000 --- a/src/DotNetty.NetUV/Native/ErrorCodeExtensions.cs +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) Johnny Z. All rights reserved. - * - * https://github.com/StormHub/NetUV - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.NetUV.Native -{ - public static class ErrorCodeExtensions - { - public static bool IsConnectionAbortError(this ErrorCode errCode) - { - switch (errCode) - { - case ErrorCode.ECANCELED: - - case ErrorCode.EPIPE: - case ErrorCode.ENOTCONN: - case ErrorCode.EINVAL: - - case ErrorCode.ENOTSOCK: - case ErrorCode.EINTR: - return true; - default: - return false; - } - } - - public static bool IsConnectionResetError(this ErrorCode errCode) - { - switch (errCode) - { - case ErrorCode.ECONNRESET: - case ErrorCode.ECONNREFUSED: - - case ErrorCode.EPIPE: - case ErrorCode.ENOTCONN: - case ErrorCode.EINVAL: - - case ErrorCode.ENOTSOCK: - case ErrorCode.EINTR: - - case ErrorCode.ETIMEDOUT: - case ErrorCode.ESHUTDOWN: - return true; - default: - return false; - } - } - } -} diff --git a/src/DotNetty.NetUV/Native/NativeHandle.cs b/src/DotNetty.NetUV/Native/NativeHandle.cs deleted file mode 100644 index ee24e3499..000000000 --- a/src/DotNetty.NetUV/Native/NativeHandle.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) Johnny Z. All rights reserved. - * - * https://github.com/StormHub/NetUV - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.NetUV.Native -{ - using System; - using System.Runtime.CompilerServices; - using DotNetty.Common.Internal.Logging; - - internal abstract class NativeHandle : IDisposable - { - protected static readonly IInternalLogger Log = InternalLoggerFactory.GetInstance(); - private IntPtr _handle; - - protected NativeHandle() - { - _handle = IntPtr.Zero; - } - - protected internal IntPtr Handle - { - [MethodImpl(InlineMethod.AggressiveOptimization)] - get => _handle; - protected set => _handle = value; - } - - internal bool IsValid - { - [MethodImpl(InlineMethod.AggressiveOptimization)] - get => _handle != IntPtr.Zero; - } - - [MethodImpl(InlineMethod.AggressiveOptimization)] - protected internal void Validate() - { - if (!IsValid) { ThrowObjectDisposedException(); } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void ThrowObjectDisposedException() - { - throw GetObjectDisposedException(); - - ObjectDisposedException GetObjectDisposedException() - { - return new ObjectDisposedException(GetType().FullName); - } - } - - internal void SetHandleAsInvalid() => _handle = IntPtr.Zero; - - protected abstract void CloseHandle(); - - private void Dispose(bool disposing) - { - try - { - if (!IsValid) { return; } -#if DEBUG - if (Log.DebugEnabled) - { - Log.Debug("Disposing {} (Finalizer {})", _handle, !disposing); - } -#endif - CloseHandle(); - } - catch (Exception exception) - { - Log.NativeHandle_error_whilst_closing_handle(_handle, exception); - - // For finalizer, we cannot allow this to escape. - if (disposing) { throw; } - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - ~NativeHandle() - { - Dispose(false); - } - } -} diff --git a/src/DotNetty.NetUV/Native/NativeMethods.cs b/src/DotNetty.NetUV/Native/NativeMethods.cs deleted file mode 100644 index 48feec4f9..000000000 --- a/src/DotNetty.NetUV/Native/NativeMethods.cs +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) Johnny Z. All rights reserved. - * - * https://github.com/StormHub/NetUV - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.NetUV.Native -{ - using System; - using System.Diagnostics; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - -#pragma warning disable IDE1006 // 命名样式 - #region uv_err_t - - internal enum uv_err_code - { - UV_OK = 0, - UV_E2BIG, - UV_EACCES, - UV_EADDRINUSE, - UV_EADDRNOTAVAIL, - UV_EAFNOSUPPORT, - UV_EAGAIN, - UV_EAI_ADDRFAMILY, - UV_EAI_AGAIN, - UV_EAI_BADFLAGS, - UV_EAI_BADHINTS, - UV_EAI_CANCELED, - UV_EAI_FAIL, - UV_EAI_FAMILY, - UV_EAI_MEMORY, - UV_EAI_NODATA, - UV_EAI_NONAME, - UV_EAI_OVERFLOW, - UV_EAI_PROTOCOL, - UV_EAI_SERVICE, - UV_EAI_SOCKTYPE, - UV_EALREADY, - UV_EBADF, - UV_EBUSY, - UV_ECANCELED, - UV_ECHARSET, - UV_ECONNABORTED, - UV_ECONNREFUSED, - UV_ECONNRESET, - UV_EDESTADDRREQ, - UV_EEXIST, - UV_EFAULT, - UV_EFBIG, - UV_EHOSTUNREACH, - UV_EINTR, - UV_EINVAL, - UV_EIO, - UV_EISCONN, - UV_EISDIR, - UV_ELOOP, - UV_EMFILE, - UV_EMSGSIZE, - UV_ENAMETOOLONG, - UV_ENETDOWN, - UV_ENETUNREACH, - UV_ENFILE, - UV_ENOBUFS, - UV_ENODEV, - UV_ENOENT, - UV_ENOMEM, - UV_ENONET, - UV_ENOPROTOOPT, - UV_ENOSPC, - UV_ENOSYS, - UV_ENOTCONN, - UV_ENOTDIR, - UV_ENOTEMPTY, - UV_ENOTSOCK, - UV_ENOTSUP, - UV_EPERM, - UV_EPIPE, - UV_EPROTO, - UV_EPROTONOSUPPORT, - UV_EPROTOTYPE, - UV_ERANGE, - UV_EROFS, - UV_ESHUTDOWN, - UV_ESPIPE, - UV_ESRCH, - UV_ETIMEDOUT, - UV_ETXTBSY, - UV_EXDEV, - UV_UNKNOWN, - UV_EOF = -4095, - UV_ENXIO, - UV_EMLINK, - } - - #endregion - - #region Native Callbacks - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void uv_close_cb(IntPtr conn); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void uv_work_cb(IntPtr watcher); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void uv_watcher_cb(IntPtr watcher, int status); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void uv_poll_cb(IntPtr handle, int status, int events); - - #endregion Native Callbacks - - internal static partial class NativeMethods - { - private const string LibraryName = "libuv"; - -#if NETCOREAPP || NETSTANDARD - [MethodImpl(InlineMethod.AggressiveOptimization)] - internal static IntPtr Allocate(int size) => Marshal.AllocCoTaskMem(size); - - [MethodImpl(InlineMethod.AggressiveOptimization)] - internal static void FreeMemory(IntPtr ptr) => Marshal.FreeCoTaskMem(ptr); -#else - [MethodImpl(InlineMethod.AggressiveOptimization)] - internal static IntPtr Allocate(int size) => Marshal.AllocHGlobal(size); - - [MethodImpl(InlineMethod.AggressiveOptimization)] - internal static void FreeMemory(IntPtr ptr) => Marshal.FreeHGlobal(ptr); -#endif - - #region Common - - internal static bool IsHandleActive(IntPtr handle) => - handle != IntPtr.Zero && (uint)uv_is_active(handle) > 0u; - - internal static void AddReference(IntPtr handle) - { - Debug.Assert(handle != IntPtr.Zero); - - uv_ref(handle); - } - - internal static void ReleaseReference(IntPtr handle) - { - Debug.Assert(handle != IntPtr.Zero); - - uv_unref(handle); - } - - internal static bool HadReference(IntPtr handle) => - handle != IntPtr.Zero && (uint)uv_has_ref(handle) > 0u; - - internal static void CloseHandle(IntPtr handle, uv_close_cb callback) - { - if (handle == IntPtr.Zero || callback is null) - { - return; - } - - int result = uv_is_closing(handle); - if (0u >= (uint)result) - { - uv_close(handle, callback); - } - } - - internal static bool IsHandleClosing(IntPtr handle) => - handle != IntPtr.Zero && (uint)uv_is_closing(handle) > 0u; - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern void uv_close(IntPtr handle, uv_close_cb close_cb); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern int uv_is_closing(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern void uv_ref(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern void uv_unref(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern int uv_has_ref(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern int uv_is_active(IntPtr handle); - - #endregion Common - - #region Error - - [MethodImpl(InlineMethod.AggressiveOptimization)] - internal static void ThrowIfError(int code) - { - if ((uint)code > SharedConstants.TooBigOrNegative) // < 0 - { - ThrowOperationException((uv_err_code)code); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowOperationException(uv_err_code error) => throw CreateError(error); - - internal static OperationException CreateError(uv_err_code error) - { - string name = GetErrorName(error); - string description = GetErrorDescription(error); - return new OperationException((int)error, name, description); - } - - private static string GetErrorDescription(uv_err_code code) - { - IntPtr ptr = uv_strerror(code); - if (ptr == IntPtr.Zero) { return null; } - return Marshal.PtrToStringAnsi(ptr); - } - - private static string GetErrorName(uv_err_code code) - { - IntPtr ptr = uv_err_name(code); - if (ptr == IntPtr.Zero) { return null; } - return Marshal.PtrToStringAnsi(ptr); - } - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr uv_strerror(uv_err_code err); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr uv_err_name(uv_err_code err); - - #endregion Error - - #region Version - - internal static Version GetVersion() - { - uint version = uv_version(); - int major = (int)(version & 0xFF0000) >> 16; - int minor = (int)(version & 0xFF00) >> 8; - int patch = (int)(version & 0xFF); - - return new Version(major, minor, patch); - } - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - private static extern uint uv_version(); - - #endregion Version - } -#pragma warning restore IDE1006 // 命名样式 -} diff --git a/src/DotNetty.NetUV/Native/OperationException.cs b/src/DotNetty.NetUV/Native/OperationException.cs deleted file mode 100644 index b9b887c7f..000000000 --- a/src/DotNetty.NetUV/Native/OperationException.cs +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Johnny Z. All rights reserved. - * - * https://github.com/StormHub/NetUV - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.NetUV.Native -{ - using System; - using DotNetty.Common.Internal; - - public sealed class OperationException : Exception - { - static readonly CachedReadConcurrentDictionary s_errorCodeCache = new CachedReadConcurrentDictionary(StringComparer.Ordinal); - static readonly Func s_convertErrorCodeFunc = e => ConvertErrorCode(e); - - public OperationException(int errorCode, string errorName, string description) - : base($"{errorName} : {description}") - { - Code = errorCode; - Name = errorName; - Description = description; - - ErrorCode = s_errorCodeCache.GetOrAdd(errorName, s_convertErrorCodeFunc); - } - - public int Code { get; } - - public string Name { get; } - - public string Description { get; } - - public ErrorCode ErrorCode { get; } - - public override string Message => $"{Name} ({ErrorCode}) : {base.Message}"; - - static ErrorCode ConvertErrorCode(string errorName) - { - if (!Enum.TryParse(errorName, true, out ErrorCode value)) - { - value = ErrorCode.UNKNOWN; - } - return value; - } - } -} diff --git a/src/DotNetty.NetUV/Native/Platform.cs b/src/DotNetty.NetUV/Native/Platform.cs deleted file mode 100644 index 439800e81..000000000 --- a/src/DotNetty.NetUV/Native/Platform.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) Johnny Z. All rights reserved. - * - * https://github.com/StormHub/NetUV - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.NetUV.Native -{ - using System.Net.Sockets; - using System.Runtime.InteropServices; - - internal static class Platform - { - static Platform() - { - IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); - IsDarwin = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); - IsUnix = IsLinux || IsDarwin; - - OSSupportsIPv6 = Socket.OSSupportsIPv6; - OSSupportsIPv4 = Socket.OSSupportsIPv4; - } - - public static readonly bool OSSupportsIPv6; - - public static readonly bool OSSupportsIPv4; - - public static readonly bool IsWindows; - - public static readonly bool IsUnix; - - public static readonly bool IsDarwin; - - public static readonly bool IsLinux; - } -} diff --git a/src/DotNetty.NetUV/Properties/AssemblyInfo.cs b/src/DotNetty.NetUV/Properties/AssemblyInfo.cs deleted file mode 100644 index 1e318919d..000000000 --- a/src/DotNetty.NetUV/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Reflection; - -[assembly: AssemblyMetadata("Serviceable", "True")] diff --git a/src/DotNetty.NetUV/Properties/Friends.cs b/src/DotNetty.NetUV/Properties/Friends.cs deleted file mode 100644 index 2d3a8eb65..000000000 --- a/src/DotNetty.NetUV/Properties/Friends.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("DotNetty.NetUV.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100d9782d5a0b850f230f71e06de2e101d8441d83e15eef715837eee38fdbf5cb369b41ec36e6e7668c18cbb09e5419c179360461e740c1cce6ffbdcf81f245e1e705482797fe42aff2d31ecd72ea87362ded3c14066746fbab4a8e1896f8b982323c84e2c1b08407c0de18b7feef1535fb972a3b26181f5a304ebd181795a46d8f")] diff --git a/src/DotNetty.NetUV/readme.md b/src/DotNetty.NetUV/readme.md deleted file mode 100644 index 8c0f187a5..000000000 --- a/src/DotNetty.NetUV/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -- This library is primarily based on the **NetUV.Core** library. -- You can refer (https://github.com/StormHub/NetUV/) for more details. diff --git a/src/DotNetty.Transport.Libuv/LoopExecutor.cs b/src/DotNetty.Transport.Libuv/AbstractUVEventLoop.cs similarity index 88% rename from src/DotNetty.Transport.Libuv/LoopExecutor.cs rename to src/DotNetty.Transport.Libuv/AbstractUVEventLoop.cs index 9365c1586..2f200e037 100644 --- a/src/DotNetty.Transport.Libuv/LoopExecutor.cs +++ b/src/DotNetty.Transport.Libuv/AbstractUVEventLoop.cs @@ -36,10 +36,10 @@ namespace DotNetty.Transport.Libuv using DotNetty.Common.Concurrency; using DotNetty.Common.Internal; using DotNetty.Transport.Channels; - using DotNetty.Transport.Libuv.Native; - using Timer = Native.Timer; + using DotNetty.Transport.Libuv.Handles; + using Timer = DotNetty.Transport.Libuv.Handles.Timer; - public abstract class LoopExecutor : SingleThreadEventLoopBase + public abstract class AbstractUVEventLoop : SingleThreadEventLoopBase { #region @@ Fields @@ @@ -49,9 +49,7 @@ public abstract class LoopExecutor : SingleThreadEventLoopBase private static long s_startTimeInitialized; internal static readonly TimeSpan DefaultBreakoutInterval = TimeSpan.FromMilliseconds(DefaultBreakoutTime); - private static readonly Func s_valueFactory = handle => new WriteRequest(handle); - private readonly ThreadLocalPool _writeRequestPool; private readonly long _preciseBreakoutInterval; private readonly ManualResetEventSlim _loopRunStart; private readonly Loop _loop; @@ -66,16 +64,14 @@ public abstract class LoopExecutor : SingleThreadEventLoopBase #region @@ Constructor @@ - protected LoopExecutor(IEventLoopGroup parent, IThreadFactory threadFactory, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) + protected AbstractUVEventLoop(IEventLoopGroup parent, IThreadFactory threadFactory, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) : base(parent, threadFactory, false, int.MaxValue, rejectedHandler) { - _writeRequestPool = new ThreadLocalPool(s_valueFactory); - _preciseBreakoutInterval = ToPreciseTime(breakoutInterval); _loop = new Loop(); - _asyncHandle = new Async(_loop, OnCallbackAction, this); - _timerHandle = new Timer(_loop, OnCallbackAction, this); + _asyncHandle = _loop.CreateAsync(OnCallbackAsyncAction, this); + _timerHandle = _loop.CreateTimer(OnCallbackTimerAction, this); _loopRunStart = new ManualResetEventSlim(false, 1); if (SharedConstants.False >= (uint)Interlocked.Exchange(ref s_startTimeInitialized, SharedConstants.True)) @@ -89,8 +85,6 @@ protected LoopExecutor(IEventLoopGroup parent, IThreadFactory threadFactory, IRe #region -- Properties -- - internal ThreadLocalPool WriteRequestPool => _writeRequestPool; - internal Loop UnsafeLoop => _loop; internal int LoopThreadId => InnerThread.Id; @@ -100,7 +94,8 @@ protected LoopExecutor(IEventLoopGroup parent, IThreadFactory threadFactory, IRe #region -- Thread -- private static readonly XParameterizedThreadStart RunAction = s => Run(s); - private static readonly Action OnCallbackAction = s => OnCallback(s); + private static readonly Action OnCallbackAsyncAction = (h, s) => OnCallback(s); + private static readonly Action OnCallbackTimerAction = (h, s) => OnCallback(s); protected sealed override XThread NewThread(IThreadFactory threadFactory) { @@ -119,11 +114,11 @@ protected override void Start() private static void Run(object state) { - var loopExecutor = (LoopExecutor)state; + var loopExecutor = (AbstractUVEventLoop)state; loopExecutor.SetCurrentExecutor(loopExecutor); _ = Task.Factory.StartNew( - executor => ((LoopExecutor)executor).StartLoop(), state, + executor => ((AbstractUVEventLoop)executor).StartLoop(), state, CancellationToken.None, TaskCreationOptions.AttachedToParent, loopExecutor.Scheduler); @@ -131,7 +126,6 @@ private static void Run(object state) private void StartLoop() { - IntPtr handle = _loop.Handle; try { UpdateLastExecutionTime(); @@ -141,17 +135,17 @@ private void StartLoop() ThrowHelper.ThrowInvalidOperationException_ExecutionState0(NotStartedState); } _loopRunStart.Set(); - _ = _loop.Run(uv_run_mode.UV_RUN_DEFAULT); + _ = _loop.RunDefault(); } catch (Exception ex) { _loopRunStart.Set(); SetExecutionState(TerminatedState); - Logger.LoopRunDefaultError(InnerThread, handle, ex); + Logger.LoopRunDefaultError(InnerThread, ex); } finally { - if (Logger.InfoEnabled) Logger.LoopThreadFinished(InnerThread, handle); + if (Logger.InfoEnabled) Logger.LoopThreadFinished(InnerThread); try { CleanupAndTerminate(false); @@ -161,7 +155,7 @@ private void StartLoop() } [MethodImpl(InlineMethod.AggressiveOptimization)] - private static void OnCallback(object state) => ((LoopExecutor)state).Run(); + private static void OnCallback(object state) => ((AbstractUVEventLoop)state).Run(); #endregion @@ -337,21 +331,19 @@ private void DoShutdown() protected override void Cleanup() { - IntPtr handle = _loop.Handle; - try { Release(); } catch (Exception ex) { - if (Logger.WarnEnabled) Logger.LoopReleaseError(InnerThread, handle, ex); + if (Logger.WarnEnabled) Logger.LoopReleaseError(InnerThread, ex); } SafeDispose(_timerHandle); SafeDispose(_asyncHandle); SafeDispose(_loop); - if (Logger.InfoEnabled) Logger.LoopDisposed(InnerThread, handle); + if (Logger.InfoEnabled) Logger.LoopDisposed(InnerThread); } private void StopLoop() diff --git a/src/DotNetty.NetUV/Buffers/ReadableBuffer.cs b/src/DotNetty.Transport.Libuv/Buffers/ReadableBuffer.cs similarity index 99% rename from src/DotNetty.NetUV/Buffers/ReadableBuffer.cs rename to src/DotNetty.Transport.Libuv/Buffers/ReadableBuffer.cs index 08b528328..0055dd153 100644 --- a/src/DotNetty.NetUV/Buffers/ReadableBuffer.cs +++ b/src/DotNetty.Transport.Libuv/Buffers/ReadableBuffer.cs @@ -17,7 +17,7 @@ namespace DotNetty.Buffers using System; using System.Collections.Generic; using System.Text; - using DotNetty.NetUV; + using DotNetty.Transport.Libuv; public readonly struct ReadableBuffer : IDisposable { diff --git a/src/DotNetty.NetUV/Buffers/ReceiveBufferSizeEstimate.cs b/src/DotNetty.Transport.Libuv/Buffers/ReceiveBufferSizeEstimate.cs similarity index 99% rename from src/DotNetty.NetUV/Buffers/ReceiveBufferSizeEstimate.cs rename to src/DotNetty.Transport.Libuv/Buffers/ReceiveBufferSizeEstimate.cs index 235b7b423..cdd01a6dc 100644 --- a/src/DotNetty.NetUV/Buffers/ReceiveBufferSizeEstimate.cs +++ b/src/DotNetty.Transport.Libuv/Buffers/ReceiveBufferSizeEstimate.cs @@ -19,7 +19,7 @@ namespace DotNetty.Buffers using System.Diagnostics; using DotNetty.Common.Utilities; using DotNetty.Common.Internal.Logging; - using DotNetty.NetUV; + using DotNetty.Transport.Libuv; internal sealed class ReceiveBufferSizeEstimate { diff --git a/src/DotNetty.NetUV/Buffers/WritableBuffer.cs b/src/DotNetty.Transport.Libuv/Buffers/WritableBuffer.cs similarity index 98% rename from src/DotNetty.NetUV/Buffers/WritableBuffer.cs rename to src/DotNetty.Transport.Libuv/Buffers/WritableBuffer.cs index 4911e19be..d01f7b159 100644 --- a/src/DotNetty.NetUV/Buffers/WritableBuffer.cs +++ b/src/DotNetty.Transport.Libuv/Buffers/WritableBuffer.cs @@ -16,7 +16,7 @@ namespace DotNetty.Buffers { using System; using System.Text; - using DotNetty.NetUV; + using DotNetty.Transport.Libuv; public readonly struct WritableBuffer : IDisposable { diff --git a/src/DotNetty.NetUV/Concurrency/Gate.cs b/src/DotNetty.Transport.Libuv/Concurrency/Gate.cs similarity index 97% rename from src/DotNetty.NetUV/Concurrency/Gate.cs rename to src/DotNetty.Transport.Libuv/Concurrency/Gate.cs index 40801ff25..53531122c 100644 --- a/src/DotNetty.NetUV/Concurrency/Gate.cs +++ b/src/DotNetty.Transport.Libuv/Concurrency/Gate.cs @@ -12,7 +12,7 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Concurrency +namespace DotNetty.Transport.Libuv.Concurrency { using System; using System.Diagnostics; diff --git a/src/DotNetty.Transport.Libuv/DispatcherEventLoop.cs b/src/DotNetty.Transport.Libuv/DispatcherEventLoop.cs index 7ea757c14..69c616011 100644 --- a/src/DotNetty.Transport.Libuv/DispatcherEventLoop.cs +++ b/src/DotNetty.Transport.Libuv/DispatcherEventLoop.cs @@ -32,9 +32,11 @@ namespace DotNetty.Transport.Libuv using System.Diagnostics; using DotNetty.Common.Concurrency; using DotNetty.Transport.Channels; + using DotNetty.Common; using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Handles; - public sealed class DispatcherEventLoop : LoopExecutor + public sealed class DispatcherEventLoop : AbstractUVEventLoop { private PipeListener _pipeListener; private IServerNativeUnsafe _nativeUnsafe; @@ -49,10 +51,7 @@ internal DispatcherEventLoop(IEventLoopGroup parent, IThreadFactory threadFactor { if (parent is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.parent); } - string pipeName = "DotNetty_" + Guid.NewGuid().ToString("n"); - PipeName = (PlatformApi.IsWindows - ? @"\\.\pipe\" - : "/tmp/") + pipeName; + PipeName = PlatformApis.GetPipeName(); Start(); } @@ -77,7 +76,7 @@ protected override void Initialize() protected override void Release() => _pipeListener.Shutdown(); - internal void Dispatch(NativeHandle handle) + internal void Dispatch(Tcp handle) { try { @@ -90,6 +89,6 @@ internal void Dispatch(NativeHandle handle) } } - internal void Accept(NativeHandle handle) => _nativeUnsafe.Accept(handle); + internal void Accept(Tcp handle) => _nativeUnsafe.Accept(handle); } } diff --git a/src/DotNetty.Transport.Libuv/DotNetty.Transport.Libuv.csproj b/src/DotNetty.Transport.Libuv/DotNetty.Transport.Libuv.csproj index f7ba82f61..0c8e15700 100644 --- a/src/DotNetty.Transport.Libuv/DotNetty.Transport.Libuv.csproj +++ b/src/DotNetty.Transport.Libuv/DotNetty.Transport.Libuv.csproj @@ -15,9 +15,6 @@ socket;tcp;protocol;netty;dotnetty;network - - - diff --git a/src/DotNetty.NetUV/Handles/Async.cs b/src/DotNetty.Transport.Libuv/Handles/Async.cs similarity index 76% rename from src/DotNetty.NetUV/Handles/Async.cs rename to src/DotNetty.Transport.Libuv/Handles/Async.cs index 1c7bf6ef1..594211a76 100644 --- a/src/DotNetty.NetUV/Handles/Async.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Async.cs @@ -12,27 +12,33 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Concurrency; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Concurrency; + using DotNetty.Transport.Libuv.Native; /// /// Async handles allow the user to “wakeup” the event loop and get /// a callback called from another thread. /// - public sealed class Async : WorkHandle + public sealed class Async : WorkHandle { private readonly Gate _gate; private volatile bool _closeScheduled; internal Async(LoopContext loop, Action callback) + : this(loop, callback is object ? (h, s) => callback(h) : null, null) + { + } + + internal Async(LoopContext loop, Action callback, object state) : base(loop, uv_handle_type.UV_ASYNC) { if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } - Callback = state => callback.Invoke((Async)state); + Callback = callback; + State = state; _gate = new Gate(); _closeScheduled = false; } @@ -56,7 +62,7 @@ public Async Send() return this; } - protected override void ScheduleClose(Action handler = null) + protected override void ScheduleClose(Action handler = null) { using (_gate.Aquire()) { @@ -64,8 +70,5 @@ protected override void ScheduleClose(Action handler = null) base.ScheduleClose(handler); } } - - public void CloseHandle(Action onClosed = null) => - base.CloseHandle(onClosed); } } diff --git a/src/DotNetty.NetUV/Handles/Check.cs b/src/DotNetty.Transport.Libuv/Handles/Check.cs similarity index 69% rename from src/DotNetty.NetUV/Handles/Check.cs rename to src/DotNetty.Transport.Libuv/Handles/Check.cs index 6ee0461b6..5d58ced6a 100644 --- a/src/DotNetty.NetUV/Handles/Check.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Check.cs @@ -12,16 +12,16 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; /// /// Check handles will run the given callback once per loop iteration, /// right after polling for i/o. /// - public sealed class Check : WorkHandle + public sealed class Check : WorkHandle { internal Check(LoopContext loop) : base(loop, uv_handle_type.UV_CHECK) @@ -29,15 +29,16 @@ internal Check(LoopContext loop) public Check Start(Action callback) { - if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + ScheduleStart(callback); + return this; + } - ScheduleStart(state => callback((Check)state)); + public Check Start(Action callback, object state) + { + ScheduleStart(callback, state); return this; } public void Stop() => StopHandle(); - - public void CloseHandle(Action onClosed = null) => - base.CloseHandle(onClosed); } } diff --git a/src/DotNetty.NetUV/Handles/FSEvent.cs b/src/DotNetty.Transport.Libuv/Handles/FSEvent.cs similarity index 91% rename from src/DotNetty.NetUV/Handles/FSEvent.cs rename to src/DotNetty.Transport.Libuv/Handles/FSEvent.cs index 60e22e070..2ff06d28f 100644 --- a/src/DotNetty.NetUV/Handles/FSEvent.cs +++ b/src/DotNetty.Transport.Libuv/Handles/FSEvent.cs @@ -12,10 +12,10 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; [Flags] public enum FSEventType @@ -71,7 +71,7 @@ internal FileSystemEvent(string fileName, FSEventType eventType, Exception error public Exception Error { get; } } - public sealed class FSEvent : ScheduleHandle + public sealed class FSEvent : ScheduleHandle { internal static readonly uv_fs_event_cb FSEventCallback = (h, f, e, s) => OnFSEventCallback(h, f, e, s); @@ -136,16 +136,5 @@ private static void OnFSEventCallback(IntPtr handle, string fileName, int events public void Stop() => StopHandle(); protected override void Close() => _eventCallback = null; - - public void CloseHandle(Action onClosed = null) - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((FSEvent)state); - } - - base.CloseHandle(handler); - } } } diff --git a/src/DotNetty.NetUV/Handles/FSPoll.cs b/src/DotNetty.Transport.Libuv/Handles/FSPoll.cs similarity index 86% rename from src/DotNetty.NetUV/Handles/FSPoll.cs rename to src/DotNetty.Transport.Libuv/Handles/FSPoll.cs index 3ba51ed05..4c425a870 100644 --- a/src/DotNetty.NetUV/Handles/FSPoll.cs +++ b/src/DotNetty.Transport.Libuv/Handles/FSPoll.cs @@ -12,10 +12,10 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; public readonly struct FSPollStatus { @@ -33,7 +33,7 @@ internal FSPollStatus(FileStatus previous, FileStatus current, Exception error) public Exception Error { get; } } - public sealed class FSPoll : ScheduleHandle + public sealed class FSPoll : ScheduleHandle { internal static readonly uv_fs_poll_cb FSPollCallback = OnFSPollCallback; private Action _pollCallback; @@ -74,14 +74,14 @@ private void OnFSPollCallback(int status, ref uv_stat_t prev, ref uv_stat_t curr FileStatus previous = null; FileStatus current = null; OperationException error = null; - if ((uint)status > SharedConstants.TooBigOrNegative) // < 0 + if (SharedConstants.TooBigOrNegative >= (uint)status) { - error = NativeMethods.CreateError((uv_err_code)status); + previous = (FileStatus)prev; + current = (FileStatus)curr; } else { - previous = (FileStatus)prev; - current = (FileStatus)curr; + error = NativeMethods.CreateError((uv_err_code)status); } _pollCallback?.Invoke(this, new FSPollStatus(previous, current, error)); @@ -102,16 +102,5 @@ private static void OnFSPollCallback(IntPtr handle, int status, ref uv_stat_t pr public void Stop() => StopHandle(); protected override void Close() => _pollCallback = null; - - public void CloseHandle(Action onClosed = null) - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((FSPoll)state); - } - - base.CloseHandle(handler); - } } } diff --git a/src/DotNetty.NetUV/Handles/FileStatus.cs b/src/DotNetty.Transport.Libuv/Handles/FileStatus.cs similarity index 95% rename from src/DotNetty.NetUV/Handles/FileStatus.cs rename to src/DotNetty.Transport.Libuv/Handles/FileStatus.cs index 59d8ed871..99d1558e2 100644 --- a/src/DotNetty.NetUV/Handles/FileStatus.cs +++ b/src/DotNetty.Transport.Libuv/Handles/FileStatus.cs @@ -12,10 +12,10 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; public sealed class FileStatus { diff --git a/src/DotNetty.NetUV/Handles/HandleContext.cs b/src/DotNetty.Transport.Libuv/Handles/HandleContext.cs similarity index 90% rename from src/DotNetty.NetUV/Handles/HandleContext.cs rename to src/DotNetty.Transport.Libuv/Handles/HandleContext.cs index 9e19eba76..bc6e6d984 100644 --- a/src/DotNetty.NetUV/Handles/HandleContext.cs +++ b/src/DotNetty.Transport.Libuv/Handles/HandleContext.cs @@ -12,12 +12,12 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Diagnostics; using System.Runtime.InteropServices; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; internal sealed unsafe class HandleContext : NativeHandle { @@ -29,7 +29,7 @@ internal HandleContext( uv_handle_type handleType, Func initializer, IntPtr loopHandle, - ScheduleHandle target, + IInternalScheduleHandle target, params object[] args) { Debug.Assert(loopHandle != IntPtr.Zero); @@ -59,11 +59,9 @@ internal HandleContext( if (Log.InfoEnabled) { Log.HandleAllocated(handleType, handle); } } - internal bool IsActive => IsValid - && NativeMethods.IsHandleActive(Handle); + internal bool IsActive => /*IsValid && */NativeMethods.IsHandleActive(Handle); - internal bool IsClosing => IsValid - && NativeMethods.IsHandleClosing(Handle); + internal bool IsClosing => /*IsValid && */NativeMethods.IsHandleClosing(Handle); internal void AddReference() { @@ -113,7 +111,7 @@ private static void OnCloseHandle(IntPtr handle) { if (handle == IntPtr.Zero) { return; } - ScheduleHandle scheduleHandle = null; + IInternalScheduleHandle scheduleHandle = null; // Get gc handle first IntPtr pHandle = ((uv_handle_t*)handle)->data; @@ -122,7 +120,7 @@ private static void OnCloseHandle(IntPtr handle) GCHandle nativeHandle = GCHandle.FromIntPtr(pHandle); if (nativeHandle.IsAllocated) { - scheduleHandle = nativeHandle.Target as ScheduleHandle; + scheduleHandle = nativeHandle.Target as IInternalScheduleHandle; nativeHandle.Free(); ((uv_handle_t*)handle)->data = IntPtr.Zero; diff --git a/src/DotNetty.NetUV/Handles/IReadCompletion.cs b/src/DotNetty.Transport.Libuv/Handles/IReadCompletion.cs similarity index 94% rename from src/DotNetty.NetUV/Handles/IReadCompletion.cs rename to src/DotNetty.Transport.Libuv/Handles/IReadCompletion.cs index 6bd699a7b..4c3b84c8b 100644 --- a/src/DotNetty.NetUV/Handles/IReadCompletion.cs +++ b/src/DotNetty.Transport.Libuv/Handles/IReadCompletion.cs @@ -12,7 +12,7 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Net; @@ -53,7 +53,7 @@ internal ReadCompletion(ref ReadableBuffer data, Exception error) public void Dispose() { IByteBuffer buffer = Data.Buffer; - if (buffer.ReferenceCount > 0) + if (buffer.IsAccessible) { buffer.Release(); } diff --git a/src/DotNetty.Transport.Libuv/Handles/IScheduleHandle.cs b/src/DotNetty.Transport.Libuv/Handles/IScheduleHandle.cs new file mode 100644 index 000000000..20ded6033 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Handles/IScheduleHandle.cs @@ -0,0 +1,53 @@ +/* + * Copyright (c) Johnny Z. All rights reserved. + * + * https://github.com/StormHub/NetUV + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) + * + * https://github.com/cuteant/dotnetty-span-fork + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +namespace DotNetty.Transport.Libuv.Handles +{ + using System; + using DotNetty.Transport.Libuv.Native; + + public interface IScheduleHandle : IDisposable + { + bool IsActive { get; } + + bool IsClosing { get; } + + bool IsValid { get; } + + object UserToken { get; set; } + + bool TryGetLoop(out Loop loop); + + void AddReference(); + + void RemoveReference(); + + bool HasReference(); + + void CloseHandle(Action onClosed); + } + + internal interface IInternalScheduleHandle : IScheduleHandle + { + uv_handle_type HandleType { get; } + + IntPtr InternalHandle { get; } + + IntPtr LoopHandle(); + + void Validate(); + + void OnHandleClosed(); + } +} diff --git a/src/DotNetty.Transport.Libuv/Handles/IServerStream.cs b/src/DotNetty.Transport.Libuv/Handles/IServerStream.cs new file mode 100644 index 000000000..44806479e --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Handles/IServerStream.cs @@ -0,0 +1,25 @@ +/* + * Copyright (c) Johnny Z. All rights reserved. + * + * https://github.com/StormHub/NetUV + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) + * + * https://github.com/cuteant/dotnetty-span-fork + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +namespace DotNetty.Transport.Libuv.Handles +{ + using System; + + internal interface IInternalServerStream : IInternalStreamHandle + { + IInternalStreamHandle NewStream(); + + void OnConnection(IInternalStreamHandle stream, Exception exception); + } +} diff --git a/src/DotNetty.NetUV/Channels/IStreamConsumer.cs b/src/DotNetty.Transport.Libuv/Handles/IStreamConsumer.cs similarity index 85% rename from src/DotNetty.NetUV/Channels/IStreamConsumer.cs rename to src/DotNetty.Transport.Libuv/Handles/IStreamConsumer.cs index c0f98af4e..885904561 100644 --- a/src/DotNetty.NetUV/Channels/IStreamConsumer.cs +++ b/src/DotNetty.Transport.Libuv/Handles/IStreamConsumer.cs @@ -12,12 +12,10 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Channels +namespace DotNetty.Transport.Libuv.Handles { - using DotNetty.NetUV.Handles; - internal interface IStreamConsumer - where T : StreamHandle + where T : IInternalStreamHandle { void Consume(T stream, IStreamReadCompletion readCompletion); } diff --git a/src/DotNetty.Transport.Libuv/Handles/IStreamHandle.cs b/src/DotNetty.Transport.Libuv/Handles/IStreamHandle.cs new file mode 100644 index 000000000..5f908d330 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Handles/IStreamHandle.cs @@ -0,0 +1,50 @@ +/* + * Copyright (c) Johnny Z. All rights reserved. + * + * https://github.com/StormHub/NetUV + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) + * + * https://github.com/cuteant/dotnetty-span-fork + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +namespace DotNetty.Transport.Libuv.Handles +{ + using System; + using DotNetty.Buffers; + using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Requests; + + public interface IStreamHandle : IScheduleHandle + { + bool IsReadable { get; } + + bool IsWritable { get; } + + void GetFileDescriptor(ref IntPtr value); + + long GetWriteQueueSize(); + + WritableBuffer Allocate(); + + void TryWrite(byte[] array); + } + + internal interface IInternalStreamHandle : IStreamHandle, IInternalScheduleHandle + { + IByteBuffer GetBuffer(ref uv_buf_t buf); + + void WriteStream(WriteRequest request); + void WriteStream(WriteRequest request, IInternalStreamHandle sendHandle); + + void ReadStart(); + + void OnReadCallback(IByteBuffer byteBuffer, int status); + + void OnAllocateCallback(out uv_buf_t buf); + } +} diff --git a/src/DotNetty.Transport.Libuv/Handles/IWorkHandle.cs b/src/DotNetty.Transport.Libuv/Handles/IWorkHandle.cs new file mode 100644 index 000000000..b10528112 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Handles/IWorkHandle.cs @@ -0,0 +1,21 @@ +/* + * Copyright (c) Johnny Z. All rights reserved. + * + * https://github.com/StormHub/NetUV + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) + * + * https://github.com/cuteant/dotnetty-span-fork + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +namespace DotNetty.Transport.Libuv.Handles +{ + internal interface IWorkHandle : IInternalScheduleHandle + { + void OnWorkCallback(); + } +} diff --git a/src/DotNetty.NetUV/Handles/Idle.cs b/src/DotNetty.Transport.Libuv/Handles/Idle.cs similarity index 69% rename from src/DotNetty.NetUV/Handles/Idle.cs rename to src/DotNetty.Transport.Libuv/Handles/Idle.cs index 22124f436..61645cf93 100644 --- a/src/DotNetty.NetUV/Handles/Idle.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Idle.cs @@ -12,16 +12,16 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; /// /// Idle handles will run the given callback once per loop iteration, /// right before the uv_prepare_t handles /// - public sealed class Idle : WorkHandle + public sealed class Idle : WorkHandle { internal Idle(LoopContext loop) : base(loop, uv_handle_type.UV_IDLE) @@ -29,16 +29,18 @@ internal Idle(LoopContext loop) public Idle Start(Action callback) { - if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + ScheduleStart(callback); - ScheduleStart(state => callback((Idle)state)); + return this; + } + + public Idle Start(Action callback, object state) + { + ScheduleStart(callback, state); return this; } public void Stop() => StopHandle(); - - public void CloseHandle(Action onClosed = null) => - base.CloseHandle(onClosed); } } diff --git a/src/DotNetty.NetUV/Handles/Loop.cs b/src/DotNetty.Transport.Libuv/Handles/Loop.cs similarity index 80% rename from src/DotNetty.NetUV/Handles/Loop.cs rename to src/DotNetty.Transport.Libuv/Handles/Loop.cs index 698350921..6de4ca51b 100644 --- a/src/DotNetty.NetUV/Handles/Loop.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Loop.cs @@ -12,12 +12,13 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; + using System.Runtime.CompilerServices; using DotNetty.Common; - using DotNetty.NetUV.Native; - using DotNetty.NetUV.Requests; + using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Requests; public sealed class Loop : IDisposable { @@ -33,6 +34,12 @@ public Loop() _handle = new LoopContext(); } + internal IntPtr InternalHandle + { + [MethodImpl(InlineMethod.AggressiveOptimization)] + get => _handle.Handle; + } + public bool IsAlive => _handle.IsAlive; public long Now => _handle.Now; @@ -65,10 +72,10 @@ public Pipe CreatePipe(bool ipc = false) return new Pipe(_handle, ipc); } - public Tcp CreateTcp() + public Tcp CreateTcp(uint flags = 0u /* AF_UNSPEC */) { _handle.Validate(); - return new Tcp(_handle); + return new Tcp(_handle, flags); } public Tty CreateTty(TtyType type) @@ -83,6 +90,18 @@ public Timer CreateTimer() return new Timer(_handle); } + public Timer CreateTimer(Action callback) + { + _handle.Validate(); + return new Timer(_handle, callback); + } + + public Timer CreateTimer(Action callback, object state) + { + _handle.Validate(); + return new Timer(_handle, callback, state); + } + public Prepare CreatePrepare() { _handle.Validate(); @@ -109,6 +128,14 @@ public Async CreateAsync(Action callback) return new Async(_handle, callback); } + public Async CreateAsync(Action callback, object state) + { + if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + + _handle.Validate(); + return new Async(_handle, callback, state); + } + public Poll CreatePoll(int fileDescriptor) { _handle.Validate(); diff --git a/src/DotNetty.NetUV/Handles/LoopContext.cs b/src/DotNetty.Transport.Libuv/Handles/LoopContext.cs similarity index 91% rename from src/DotNetty.NetUV/Handles/LoopContext.cs rename to src/DotNetty.Transport.Libuv/Handles/LoopContext.cs index dbb3148fc..4955b5154 100644 --- a/src/DotNetty.NetUV/Handles/LoopContext.cs +++ b/src/DotNetty.Transport.Libuv/Handles/LoopContext.cs @@ -12,11 +12,11 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Runtime.InteropServices; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; internal sealed unsafe class LoopContext : NativeHandle { @@ -44,9 +44,7 @@ public LoopContext() if (Log.InfoEnabled) { Log.Loop_allocated(handle); } } - public bool IsAlive => - IsValid - && NativeMethods.IsLoopAlive(Handle); + public bool IsAlive => /*IsValid && */NativeMethods.IsLoopAlive(Handle); public long Now { @@ -66,10 +64,14 @@ public long NowInHighResolution } } - public int ActiveHandleCount() => - IsValid - ? (int)((uv_loop_t*)Handle)->active_handles - : 0; + public int ActiveHandleCount() + { + if (IsValid) + { + return (int)((uv_loop_t*)Handle)->active_handles; + } + return 0; + } public void UpdateTime() { @@ -98,10 +100,7 @@ public void Stop() protected override void CloseHandle() { IntPtr handle = Handle; - if (handle == IntPtr.Zero) - { - return; - } + if (handle == IntPtr.Zero) { return; } // Get gc handle before close loop IntPtr pHandle = ((uv_loop_t*)handle)->data; @@ -127,10 +126,7 @@ protected override void CloseHandle() #if DEBUG if (Log.DebugEnabled) { Log.Debug($"Loop {handle} close result = {result}, count = {count}."); } #endif - if (0u >= (uint)result) - { - break; - } + if (0u >= (uint)result) { break; } #if DEBUG else { diff --git a/src/DotNetty.NetUV/Handles/Pipe.cs b/src/DotNetty.Transport.Libuv/Handles/Pipe.cs similarity index 57% rename from src/DotNetty.NetUV/Handles/Pipe.cs rename to src/DotNetty.Transport.Libuv/Handles/Pipe.cs index 81cf8f032..fbe2db711 100644 --- a/src/DotNetty.NetUV/Handles/Pipe.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Pipe.cs @@ -12,13 +12,13 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.Buffers; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Native; - public sealed class Pipe : ServerStream + public sealed class Pipe : ServerStream { private bool _ipc; @@ -72,38 +72,6 @@ public int SetReceiveBufferSize(int value) return ReceiveBufferSize(value); } - public Pipe OnRead( - Action onAccept, - Action onError, - Action onCompleted = null) - { - if (onAccept is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onAccept); } - if (onError is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onError); } - - base.OnRead( - (stream, buffer) => onAccept((Pipe)stream, buffer), - (stream, error) => onError((Pipe)stream, error), - stream => onCompleted?.Invoke((Pipe)stream)); - - return this; - } - - public Pipe OnRead(Action onRead) - { - if (onRead is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onRead); } - - base.OnRead((stream, completion) => onRead((Pipe)stream, completion)); - return this; - } - - public void QueueWriteStream(WritableBuffer writableBuffer, Action completion) => - base.QueueWriteStream(writableBuffer, - (streamHandle, exception) => completion((Pipe)streamHandle, exception)); - - public void QueueWriteStream(WritableBuffer writableBuffer, Tcp sendHandle, Action completion) => - base.QueueWriteStream(writableBuffer, sendHandle, - (streamHandle, exception) => completion((Pipe)streamHandle, exception)); - public Pipe Bind(string name) { if (string.IsNullOrEmpty(name)) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); } @@ -140,11 +108,11 @@ public int PendingCount() return NativeMethods.PipePendingCount(InternalHandle); } - public unsafe StreamHandle CreatePendingType() + public unsafe IStreamHandle CreatePendingType() { Validate(); - StreamHandle handle = null; + IInternalStreamHandle handle = null; int count = PendingCount(); if (count > 0) { @@ -152,18 +120,12 @@ public unsafe StreamHandle CreatePendingType() var loop = HandleContext.GetTarget(loopHandle); uv_handle_type handleType = NativeMethods.PipePendingType(InternalHandle); - switch (handleType) + handle = handleType switch { - case uv_handle_type.UV_TCP: - handle = new Tcp(loop); - break; - case uv_handle_type.UV_NAMED_PIPE: - handle = new Pipe(loop); - break; - default: - throw ThrowHelper.GetInvalidOperationException_uv_handle_type_not_supported_or_IPC_over_Pipe_is_disabled(handleType); - } - + uv_handle_type.UV_TCP => new Tcp(loop), + uv_handle_type.UV_NAMED_PIPE => new Pipe(loop), + _ => throw ThrowHelper.GetInvalidOperationException_uv_handle_type_not_supported_or_IPC_over_Pipe_is_disabled(handleType), + }; NativeMethods.StreamAccept(InternalHandle, handle.InternalHandle); handle.ReadStart(); } @@ -171,25 +133,18 @@ public unsafe StreamHandle CreatePendingType() return handle; } - protected internal override unsafe StreamHandle NewStream() + internal override unsafe IInternalStreamHandle NewStream() { IntPtr loopHandle = ((uv_stream_t*)InternalHandle)->loop; var loop = HandleContext.GetTarget(loopHandle); uv_handle_type type = ((uv_stream_t*)InternalHandle)->type; - StreamHandle client; - switch (type) + IInternalStreamHandle client = type switch { - case uv_handle_type.UV_NAMED_PIPE: - client = new Pipe(loop, _ipc); - break; - case uv_handle_type.UV_TCP: - client = new Tcp(loop); - break; - default: - throw ThrowHelper.GetInvalidOperationException_Pipe_IPC_handle_not_supported(type); - } - + uv_handle_type.UV_NAMED_PIPE => new Pipe(loop, _ipc), + uv_handle_type.UV_TCP => new Tcp(loop), + _ => throw ThrowHelper.GetInvalidOperationException_Pipe_IPC_handle_not_supported(type), + }; NativeMethods.StreamAccept(InternalHandle, client.InternalHandle); if (!_ipc) { @@ -210,27 +165,10 @@ protected internal override unsafe StreamHandle NewStream() public Pipe Listen(Action onConnection, int backlog = DefaultBacklog, bool useIpc = false) { - if (onConnection is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onConnection); } - if ((uint)(backlog - 1) > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_Positive(backlog, ExceptionArgument.backlog); } - _ipc = useIpc; - StreamListen((handle, exception) => onConnection((Pipe)handle, exception), backlog); + StreamListen(onConnection, backlog); return this; } - - public void Shutdown(Action completedAction = null) => - base.Shutdown((state, error) => completedAction?.Invoke((Pipe)state, error)); - - public void CloseHandle(Action onClosed = null) - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((Pipe)state); - } - - base.CloseHandle(handler); - } } } diff --git a/src/DotNetty.NetUV/Handles/Pipeline.cs b/src/DotNetty.Transport.Libuv/Handles/Pipeline.cs similarity index 83% rename from src/DotNetty.NetUV/Handles/Pipeline.cs rename to src/DotNetty.Transport.Libuv/Handles/Pipeline.cs index 635a9bc0c..a758c000d 100644 --- a/src/DotNetty.NetUV/Handles/Pipeline.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Pipeline.cs @@ -12,31 +12,31 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Diagnostics; using DotNetty.Buffers; using DotNetty.Common.Internal.Logging; - using DotNetty.NetUV.Channels; - using DotNetty.NetUV.Native; - using DotNetty.NetUV.Requests; + using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Requests; - internal sealed class Pipeline : IDisposable + internal sealed class Pipeline : IDisposable + where THandle : IInternalStreamHandle { - private static readonly IInternalLogger Log = InternalLoggerFactory.GetInstance(); + private static readonly IInternalLogger Log = InternalLoggerFactory.GetInstance("DotNetty.Transport.Libuv.Handles.Pipeline"); - private readonly StreamHandle _streamHandle; + private readonly THandle _streamHandle; private readonly PooledByteBufferAllocator _allocator; private readonly ReceiveBufferSizeEstimate _receiveBufferSizeEstimate; private readonly PendingRead _pendingRead; - private IStreamConsumer _streamConsumer; + private IStreamConsumer _streamConsumer; - internal Pipeline(StreamHandle streamHandle) + internal Pipeline(THandle streamHandle) : this(streamHandle, PooledByteBufferAllocator.Default) { } - internal Pipeline(StreamHandle streamHandle, PooledByteBufferAllocator allocator) + internal Pipeline(THandle streamHandle, PooledByteBufferAllocator allocator) { Debug.Assert(streamHandle is object); Debug.Assert(allocator is object); @@ -47,7 +47,7 @@ internal Pipeline(StreamHandle streamHandle, PooledByteBufferAllocator allocator _pendingRead = new PendingRead(); } - internal void Consumer(IStreamConsumer consumer) + internal void Consumer(IStreamConsumer consumer) { Debug.Assert(consumer is object); _streamConsumer = consumer; @@ -61,7 +61,7 @@ internal uv_buf_t AllocateReadBuffer() #if DEBUG if (Log.TraceEnabled) { - Log.Trace("{} receive buffer allocated size = {}", nameof(Pipeline), buffer.Capacity); + Log.Trace("{} receive buffer allocated size = {}", nameof(Pipeline), buffer.Capacity); } #endif @@ -111,7 +111,7 @@ private void InvokeRead(IByteBuffer byteBuffer, int size, Exception error = null } } - internal void QueueWrite(IByteBuffer buf, Action completion) + internal void QueueWrite(IByteBuffer buf, Action completion) { Debug.Assert(buf is object); @@ -131,7 +131,7 @@ internal void QueueWrite(IByteBuffer buf, Action comple } } - internal void QueueWrite(IByteBuffer bufferRef, StreamHandle sendHandle, Action completion) + internal void QueueWrite(IByteBuffer bufferRef, THandle sendHandle, Action completion) { Debug.Assert(bufferRef is object && sendHandle is object); @@ -159,15 +159,13 @@ public void Dispose() private sealed class StreamReadCompletion : ReadCompletion, IStreamReadCompletion { - private readonly bool _completed; - internal StreamReadCompletion(ref ReadableBuffer data, Exception error, bool completed) : base(ref data, error) { - _completed = completed; + Completed = completed; } - public bool Completed => _completed; + public bool Completed { get; } } } } diff --git a/src/DotNetty.NetUV/Handles/Poll.cs b/src/DotNetty.Transport.Libuv/Handles/Poll.cs similarity index 83% rename from src/DotNetty.NetUV/Handles/Poll.cs rename to src/DotNetty.Transport.Libuv/Handles/Poll.cs index edceaf2ec..213d502aa 100644 --- a/src/DotNetty.NetUV/Handles/Poll.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Poll.cs @@ -12,18 +12,19 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; [Flags] public enum PollMask { None = 0, - Readable = 1, // UV_READABLE - Writable = 2, // UV_WRITABLE - Disconnect = 4 // UV_DISCONNECT + Readable = 1, // UV_READABLE + Writable = 2, // UV_WRITABLE + Disconnect = 4, // UV_DISCONNECT (v1.9.0) + Prioritized = 8, // UV_PRIORITIZED (v1.14.0) }; public readonly struct PollStatus @@ -39,7 +40,7 @@ internal PollStatus(PollMask mask, Exception error) public Exception Error { get; } } - public sealed class Poll : ScheduleHandle + public sealed class Poll : ScheduleHandle { internal static readonly uv_poll_cb PollCallback = (h, s, e) => OnPollCallback(h, s, e); @@ -82,13 +83,13 @@ private void OnPollCallback(int status, int events) { OperationException error = null; var mask = PollMask.None; - if ((uint)status > SharedConstants.TooBigOrNegative) // < 0 + if (SharedConstants.TooBigOrNegative >= (uint)status) { - error = NativeMethods.CreateError((uv_err_code)status); + mask = (PollMask)events; } else { - mask = (PollMask)events; + error = NativeMethods.CreateError((uv_err_code)status); } _pollCallback?.Invoke(this, new PollStatus(mask, error)); @@ -109,16 +110,5 @@ private static void OnPollCallback(IntPtr handle, int status, int events) public void Stop() => StopHandle(); protected override void Close() => _pollCallback = null; - - public void CloseHandle(Action onClosed = null) - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((Poll)state); - } - - base.CloseHandle(handler); - } } } diff --git a/src/DotNetty.NetUV/Handles/Prepare.cs b/src/DotNetty.Transport.Libuv/Handles/Prepare.cs similarity index 69% rename from src/DotNetty.NetUV/Handles/Prepare.cs rename to src/DotNetty.Transport.Libuv/Handles/Prepare.cs index dabaabbe4..964d1caa9 100644 --- a/src/DotNetty.NetUV/Handles/Prepare.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Prepare.cs @@ -12,16 +12,16 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; /// /// Prepare handles will run the given callback once per loop iteration, /// right before polling for i/o. /// - public sealed class Prepare : WorkHandle + public sealed class Prepare : WorkHandle { internal Prepare(LoopContext loop) : base(loop, uv_handle_type.UV_PREPARE) @@ -29,15 +29,16 @@ internal Prepare(LoopContext loop) public Prepare Start(Action callback) { - if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + ScheduleStart(callback); + return this; + } - ScheduleStart(state => callback((Prepare)state)); + public Prepare Start(Action callback, object state) + { + ScheduleStart(callback, state); return this; } public void Stop() => StopHandle(); - - public void CloseHandle(Action onClosed = null) => - base.CloseHandle(onClosed); } } diff --git a/src/DotNetty.NetUV/Channels/ReadStreamConsumer.cs b/src/DotNetty.Transport.Libuv/Handles/ReadStreamConsumer.cs similarity index 76% rename from src/DotNetty.NetUV/Channels/ReadStreamConsumer.cs rename to src/DotNetty.Transport.Libuv/Handles/ReadStreamConsumer.cs index 12f948921..d543728ee 100644 --- a/src/DotNetty.NetUV/Channels/ReadStreamConsumer.cs +++ b/src/DotNetty.Transport.Libuv/Handles/ReadStreamConsumer.cs @@ -12,24 +12,23 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Channels +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Handles; internal sealed class ReadStreamConsumer : IStreamConsumer - where T : StreamHandle + where T : IInternalStreamHandle { - private readonly Action readAction; + private readonly Action _readAction; public ReadStreamConsumer(Action readAction) { if (readAction is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.readAction); } - this.readAction = readAction; + _readAction = readAction; } public void Consume(T stream, IStreamReadCompletion readCompletion) => - this.readAction(stream, readCompletion); + _readAction(stream, readCompletion); } } diff --git a/src/DotNetty.NetUV/Handles/ScheduleHandle.cs b/src/DotNetty.Transport.Libuv/Handles/ScheduleHandle (Of T).cs similarity index 64% rename from src/DotNetty.NetUV/Handles/ScheduleHandle.cs rename to src/DotNetty.Transport.Libuv/Handles/ScheduleHandle (Of T).cs index ba5019eaf..edc129cd0 100644 --- a/src/DotNetty.NetUV/Handles/ScheduleHandle.cs +++ b/src/DotNetty.Transport.Libuv/Handles/ScheduleHandle (Of T).cs @@ -12,25 +12,24 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Diagnostics; using System.Runtime.CompilerServices; using DotNetty.Common.Internal.Logging; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; - public abstract class ScheduleHandle : IDisposable + public abstract class ScheduleHandle : IInternalScheduleHandle, IDisposable + where THandle : ScheduleHandle { - protected static readonly IInternalLogger Log = InternalLoggerFactory.GetInstance(); + protected static readonly IInternalLogger Log = InternalLoggerFactory.GetInstance(typeof(THandle)); private readonly HandleContext _handle; - private Action _closeCallback; + private readonly uv_handle_type _handleType; + private Action _closeCallback; - internal ScheduleHandle( - LoopContext loop, - uv_handle_type handleType, - object[] args = null) + internal ScheduleHandle(LoopContext loop, uv_handle_type handleType, object[] args = null) { if (loop is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.loop); } @@ -38,7 +37,7 @@ internal ScheduleHandle( Debug.Assert(initialHandle is object); _handle = initialHandle; - HandleType = handleType; + _handleType = handleType; } public bool IsActive => _handle.IsActive; @@ -53,24 +52,32 @@ public bool IsValid public object UserToken { get; set; } + IntPtr IInternalScheduleHandle.InternalHandle + { + [MethodImpl(InlineMethod.AggressiveOptimization)] + get => _handle.Handle; + } + internal IntPtr InternalHandle { [MethodImpl(InlineMethod.AggressiveOptimization)] get => _handle.Handle; } - internal uv_handle_type HandleType { get; } + internal uv_handle_type HandleType => _handleType; - internal void OnHandleClosed() + uv_handle_type IInternalScheduleHandle.HandleType => _handleType; + + void IInternalScheduleHandle.OnHandleClosed() { try { _handle.SetHandleAsInvalid(); - _closeCallback?.Invoke(this); + _closeCallback?.Invoke((THandle)this); } catch (Exception exception) { - Log.Handle_close_handle_callback_error(HandleType, exception); + Log.Handle_close_handle_callback_error(_handleType, exception); } finally { @@ -79,19 +86,24 @@ internal void OnHandleClosed() } } + void IInternalScheduleHandle.Validate() => this.Validate(); + [MethodImpl(InlineMethod.AggressiveOptimization)] internal void Validate() => _handle.Validate(); + unsafe IntPtr IInternalScheduleHandle.LoopHandle() + { + Validate(); + return ((uv_handle_t*)InternalHandle)->loop; + } + public unsafe bool TryGetLoop(out Loop loop) { loop = null; try { IntPtr nativeHandle = InternalHandle; - if (nativeHandle == IntPtr.Zero) - { - return false; - } + if (nativeHandle == IntPtr.Zero) { return false; } IntPtr loopHandle = ((uv_handle_t*)nativeHandle)->loop; if (loopHandle != IntPtr.Zero) @@ -103,12 +115,23 @@ public unsafe bool TryGetLoop(out Loop loop) } catch (Exception exception) { - Log.Failed_to_get_loop(HandleType, exception); + Log.Failed_to_get_loop(_handleType, exception); return false; } } - protected internal void CloseHandle(Action handler = null) + void IScheduleHandle.CloseHandle(Action onClosed) + { + Action handler = null; + if (onClosed is object) + { + handler = state => onClosed(state); + } + + CloseHandle(handler); + } + + public void CloseHandle(Action handler = null) { try { @@ -116,12 +139,12 @@ protected internal void CloseHandle(Action handler = null) } catch (Exception exception) { - Log.Failed_to_close_handle(HandleType, exception); + Log.Failed_to_close_handle(_handleType, exception); throw; } } - protected virtual void ScheduleClose(Action handler = null) + protected virtual void ScheduleClose(Action handler = null) { if (!IsValid) { return; } @@ -136,7 +159,7 @@ protected void StopHandle() { if (!IsValid) { return; } - NativeMethods.Stop(HandleType, _handle.Handle); + NativeMethods.Stop(_handleType, _handle.Handle); } public void AddReference() diff --git a/src/DotNetty.NetUV/Handles/ServerStream.cs b/src/DotNetty.Transport.Libuv/Handles/ServerStream (Of T).cs similarity index 54% rename from src/DotNetty.NetUV/Handles/ServerStream.cs rename to src/DotNetty.Transport.Libuv/Handles/ServerStream (Of T).cs index a4eb8d86c..b69d31262 100644 --- a/src/DotNetty.NetUV/Handles/ServerStream.cs +++ b/src/DotNetty.Transport.Libuv/Handles/ServerStream (Of T).cs @@ -12,18 +12,17 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; - public abstract class ServerStream : StreamHandle + public abstract class ServerStream : StreamHandle, IInternalServerStream + where THandle : ServerStream { - internal const int DefaultBacklog = 128; + internal const int DefaultBacklog = ServerStream.DefaultBacklog; - internal static readonly uv_watcher_cb ConnectionCallback = (h, s) => OnConnectionCallback(h, s); - - private Action _connectionHandler; + private Action _connectionHandler; internal ServerStream( LoopContext loop, @@ -32,9 +31,13 @@ internal ServerStream( : base(loop, handleType, args) { } - protected internal abstract StreamHandle NewStream(); + void IInternalServerStream.OnConnection(IInternalStreamHandle handle, Exception exception) => _connectionHandler((THandle)handle, exception); + + IInternalStreamHandle IInternalServerStream.NewStream() => NewStream(); + + internal abstract IInternalStreamHandle NewStream(); - public void StreamListen(Action onConnection, int backlog = DefaultBacklog) + protected void StreamListen(Action onConnection, int backlog = DefaultBacklog) { if (onConnection is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onConnection); } if ((uint)(backlog - 1) > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_Positive(backlog, ExceptionArgument.backlog); } @@ -63,32 +66,5 @@ protected override void Close() _connectionHandler = null; base.Close(); } - - private static void OnConnectionCallback(IntPtr handle, int status) - { - var server = HandleContext.GetTarget(handle); - if (server is null) { return; } - - StreamHandle client = null; - Exception error = null; - try - { - if ((uint)status > SharedConstants.TooBigOrNegative) // < 0 - { - error = NativeMethods.CreateError((uv_err_code)status); - } - else - { - client = server.NewStream(); - } - - server._connectionHandler(client, error); - } - catch - { - client?.Dispose(); - throw; - } - } } } diff --git a/src/DotNetty.Transport.Libuv/Handles/ServerStream.cs b/src/DotNetty.Transport.Libuv/Handles/ServerStream.cs new file mode 100644 index 000000000..7964e0a78 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Handles/ServerStream.cs @@ -0,0 +1,53 @@ +/* + * Copyright (c) Johnny Z. All rights reserved. + * + * https://github.com/StormHub/NetUV + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) + * + * https://github.com/cuteant/dotnetty-span-fork + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +namespace DotNetty.Transport.Libuv.Handles +{ + using System; + using DotNetty.Transport.Libuv.Native; + + internal static class ServerStream + { + internal const int DefaultBacklog = 128; + + internal static readonly uv_watcher_cb ConnectionCallback = (h, s) => OnConnectionCallback(h, s); + + private static void OnConnectionCallback(IntPtr handle, int status) + { + var server = HandleContext.GetTarget(handle); + if (server is null) { return; } + + IInternalStreamHandle client = null; + OperationException error = null; + try + { + if (SharedConstants.TooBigOrNegative >= (uint)status) + { + client = server.NewStream(); + } + else + { + error = NativeMethods.CreateError((uv_err_code)status); + } + + server.OnConnection(client, error); + } + catch + { + client?.Dispose(); + throw; + } + } + } +} diff --git a/src/DotNetty.NetUV/Handles/Signal.cs b/src/DotNetty.Transport.Libuv/Handles/Signal.cs similarity index 82% rename from src/DotNetty.NetUV/Handles/Signal.cs rename to src/DotNetty.Transport.Libuv/Handles/Signal.cs index 6994dd93a..d5642ae16 100644 --- a/src/DotNetty.NetUV/Handles/Signal.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Signal.cs @@ -12,12 +12,12 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; - public sealed class Signal : ScheduleHandle + public sealed class Signal : ScheduleHandle { internal static readonly uv_watcher_cb SignalCallback = (h, s) => OnSignalCallback(h, s); @@ -66,16 +66,5 @@ private static void OnSignalCallback(IntPtr handle, int signum) public void Stop() => StopHandle(); protected override void Close() => _signalCallback = null; - - public void CloseHandle(Action onClosed = null) - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((Signal)state); - } - - base.CloseHandle(handler); - } } } diff --git a/src/DotNetty.NetUV/Channels/StreamConsumer.cs b/src/DotNetty.Transport.Libuv/Handles/StreamConsumer.cs similarity index 76% rename from src/DotNetty.NetUV/Channels/StreamConsumer.cs rename to src/DotNetty.Transport.Libuv/Handles/StreamConsumer.cs index 8220620e2..a5ece8712 100644 --- a/src/DotNetty.NetUV/Channels/StreamConsumer.cs +++ b/src/DotNetty.Transport.Libuv/Handles/StreamConsumer.cs @@ -12,15 +12,17 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Channels +namespace DotNetty.Transport.Libuv.Handles { using System; using DotNetty.Buffers; - using DotNetty.NetUV.Handles; internal sealed class StreamConsumer : IStreamConsumer - where T : StreamHandle + where T : IInternalStreamHandle { + private static readonly Action s_onCompleted = s => OnCompleted(s); + private static readonly Action s_onClosed = s => OnClosed(s); + private readonly Action _onAccept; private readonly Action _onError; private readonly Action _onCompleted; @@ -35,20 +37,21 @@ public StreamConsumer( _onAccept = onAccept; _onError = onError; - _onCompleted = onCompleted ?? OnCompleted; + _onCompleted = onCompleted ?? s_onCompleted; } public void Consume(T stream, IStreamReadCompletion readCompletion) { try { - if (readCompletion.Error is object) + var error = readCompletion.Error; + if (error is null) { - _onError(stream, readCompletion.Error); + _onAccept(stream, readCompletion.Data); } else { - _onAccept(stream, readCompletion.Data); + _onError(stream, error); } if (readCompletion.Completed) @@ -62,8 +65,8 @@ public void Consume(T stream, IStreamReadCompletion readCompletion) } } - private static void OnCompleted(T stream) => stream.CloseHandle(OnClosed); + private static void OnCompleted(T stream) => stream.CloseHandle(s_onClosed); - private static void OnClosed(StreamHandle streamHandle) => streamHandle.Dispose(); + private static void OnClosed(IScheduleHandle streamHandle) => streamHandle.Dispose(); } } diff --git a/src/DotNetty.NetUV/Handles/StreamHandle.cs b/src/DotNetty.Transport.Libuv/Handles/StreamHandle (Of T).cs similarity index 76% rename from src/DotNetty.NetUV/Handles/StreamHandle.cs rename to src/DotNetty.Transport.Libuv/Handles/StreamHandle (Of T).cs index 6438d00ca..da4001720 100644 --- a/src/DotNetty.NetUV/Handles/StreamHandle.cs +++ b/src/DotNetty.Transport.Libuv/Handles/StreamHandle (Of T).cs @@ -12,21 +12,18 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Diagnostics; using DotNetty.Buffers; - using DotNetty.NetUV.Channels; - using DotNetty.NetUV.Native; - using DotNetty.NetUV.Requests; + using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Requests; - public abstract class StreamHandle : ScheduleHandle + public abstract class StreamHandle : ScheduleHandle, IInternalStreamHandle + where THandle : StreamHandle { - internal static readonly uv_alloc_cb AllocateCallback = OnAllocateCallback; - internal static readonly uv_read_cb ReadCallback = OnReadCallback; - - private readonly Pipeline _pipeline; + private readonly Pipeline _pipeline; internal StreamHandle( LoopContext loop, @@ -34,7 +31,7 @@ internal StreamHandle( params object[] args) : base(loop, handleType, args) { - _pipeline = new Pipeline(this); + _pipeline = new Pipeline((THandle)this); } public bool IsReadable => NativeMethods.IsStreamReadable(InternalHandle); @@ -71,37 +68,37 @@ public unsafe long GetWriteQueueSize() public WritableBuffer Allocate() => _pipeline.Allocate(); - public void OnRead( - Action onAccept, - Action onError, - Action onCompleted = null) + public virtual void OnRead( + Action onAccept, + Action onError, + Action onCompleted = null) { if (onAccept is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onAccept); } if (onError is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onError); } - var consumer = new StreamConsumer(onAccept, onError, onCompleted); + var consumer = new StreamConsumer(onAccept, onError, onCompleted); _pipeline.Consumer(consumer); } - public void OnRead(Action onRead) + public virtual void OnRead(Action onRead) { if (onRead is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onRead); } - var consumer = new ReadStreamConsumer(onRead); + var consumer = new ReadStreamConsumer(onRead); _pipeline.Consumer(consumer); } - public void Shutdown(Action completion = null) + public void Shutdown(Action completion = null) { if (!IsValid) { return; } - StreamShutdown streamShutdown = null; + StreamShutdown streamShutdown = null; try { - streamShutdown = new StreamShutdown(this, completion); + streamShutdown = new StreamShutdown((THandle)this, completion); } catch (Exception exception) { @@ -118,24 +115,13 @@ public void Shutdown(Action completion = null) Log.Handle_failed_to_shutdown(HandleType, InternalHandle, error); } - StreamShutdown.Completed(completion, this, error); + StreamShutdown.Completed(completion, (THandle)this, error); streamShutdown?.Dispose(); } } - public void CloseHandle(Action callback = null) - { - Action handler = null; - if (callback is object) - { - handler = state => callback((StreamHandle)state); - } - - base.CloseHandle(handler); - } - public void QueueWriteStream(WritableBuffer writableBuffer, - Action completion) + Action completion) { if (completion is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.completion); } @@ -145,8 +131,8 @@ public void QueueWriteStream(WritableBuffer writableBuffer, _pipeline.QueueWrite(buffer, completion); } - public void QueueWriteStream(WritableBuffer writableBuffer, StreamHandle sendHandle, - Action completion) + public void QueueWriteStream(WritableBuffer writableBuffer, THandle sendHandle, + Action completion) { if (completion is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.completion); } if (sendHandle is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.sendHandle); } @@ -157,7 +143,7 @@ public void QueueWriteStream(WritableBuffer writableBuffer, StreamHandle sendHan _pipeline.QueueWrite(buffer, sendHandle, completion); } - public void QueueWriteStream(byte[] array, Action completion) + public void QueueWriteStream(byte[] array, Action completion) { if (array is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); } @@ -165,7 +151,7 @@ public void QueueWriteStream(byte[] array, Action compl } public void QueueWriteStream(byte[] array, int offset, int count, - Action completion) + Action completion) { if (array is null || 0u >= (uint)array.Length) { return; } if ((uint)count > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); } @@ -175,8 +161,7 @@ public void QueueWriteStream(byte[] array, int offset, int count, _pipeline.QueueWrite(buffer, completion); } - public void QueueWriteStream(byte[] array, StreamHandle sendHandle, - Action completion) + public void QueueWriteStream(byte[] array, THandle sendHandle, Action completion) { if (array is null) { return; } @@ -184,8 +169,7 @@ public void QueueWriteStream(byte[] array, StreamHandle sendHandle, } public void QueueWriteStream(byte[] array, int offset, int count, - StreamHandle sendHandle, - Action completion) + THandle sendHandle, Action completion) { if (array is null || 0u >= (uint)array.Length) { return; } if ((uint)count > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); } @@ -195,7 +179,7 @@ public void QueueWriteStream(byte[] array, int offset, int count, _pipeline.QueueWrite(buffer, sendHandle, completion); } - internal unsafe void WriteStream(WriteRequest request) + unsafe void IInternalStreamHandle.WriteStream(WriteRequest request) { Debug.Assert(request is object); @@ -215,7 +199,7 @@ internal unsafe void WriteStream(WriteRequest request) } } - internal unsafe void WriteStream(WriteRequest request, StreamHandle sendHandle) + unsafe void IInternalStreamHandle.WriteStream(WriteRequest request, IInternalStreamHandle sendHandle) { Debug.Assert(request is object); Debug.Assert(sendHandle is object); @@ -270,6 +254,10 @@ internal unsafe void TryWrite(byte[] array, int offset, int count) } } + IByteBuffer IInternalStreamHandle.GetBuffer(ref uv_buf_t buf) => _pipeline.GetBuffer(ref buf); + + void IInternalStreamHandle.ReadStart() => ReadStart(); + internal void ReadStart() { Validate(); @@ -298,7 +286,7 @@ internal void ReadStop() protected override void Close() => _pipeline.Dispose(); - private void OnReadCallback(IByteBuffer byteBuffer, int status) + void IInternalStreamHandle.OnReadCallback(IByteBuffer byteBuffer, int status) { // // nread is > 0 if there is data available or < 0 on error. @@ -310,7 +298,7 @@ private void OnReadCallback(IByteBuffer byteBuffer, int status) Debug.Assert(byteBuffer is object); // For status = 0 (Nothing to read) - if (status >= 0) + if (SharedConstants.TooBigOrNegative >= (uint)status) // status >= 0 { #if DEBUG if (Log.DebugEnabled) @@ -324,7 +312,7 @@ private void OnReadCallback(IByteBuffer byteBuffer, int status) } Exception exception = null; - if (status != (int)uv_err_code.UV_EOF) // Stream end is not an error + if (status != NativeMethods.EOF) // Stream end is not an error { exception = NativeMethods.CreateError((uv_err_code)status); Log.Handle_read_error(HandleType, InternalHandle, status, exception); @@ -340,22 +328,9 @@ private void OnReadCallback(IByteBuffer byteBuffer, int status) ReadStop(); } - private static void OnReadCallback(IntPtr handle, IntPtr nread, ref uv_buf_t buf) - { - var stream = HandleContext.GetTarget(handle); - IByteBuffer byteBuffer = stream._pipeline.GetBuffer(ref buf); - stream.OnReadCallback(byteBuffer, (int)nread.ToInt64()); - } - - private void OnAllocateCallback(out uv_buf_t buf) + void IInternalStreamHandle.OnAllocateCallback(out uv_buf_t buf) { buf = _pipeline.AllocateReadBuffer(); } - - private static void OnAllocateCallback(IntPtr handle, IntPtr suggestedSize, out uv_buf_t buf) - { - var stream = HandleContext.GetTarget(handle); - stream.OnAllocateCallback(out buf); - } } } diff --git a/src/DotNetty.Transport.Libuv/Handles/StreamHandle.cs b/src/DotNetty.Transport.Libuv/Handles/StreamHandle.cs new file mode 100644 index 000000000..303807de8 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Handles/StreamHandle.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) Johnny Z. All rights reserved. + * + * https://github.com/StormHub/NetUV + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) + * + * https://github.com/cuteant/dotnetty-span-fork + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +namespace DotNetty.Transport.Libuv.Handles +{ + using System; + using DotNetty.Buffers; + using DotNetty.Transport.Libuv.Native; + + internal static class StreamHandle + { + internal static readonly uv_alloc_cb AllocateCallback = OnAllocateCallback; + internal static readonly uv_read_cb ReadCallback = OnReadCallback; + + private static void OnReadCallback(IntPtr handle, IntPtr nread, ref uv_buf_t buf) + { + var stream = HandleContext.GetTarget(handle); + IByteBuffer byteBuffer = stream.GetBuffer(ref buf); + stream.OnReadCallback(byteBuffer, (int)nread.ToInt64()); + } + + private static void OnAllocateCallback(IntPtr handle, IntPtr suggestedSize, out uv_buf_t buf) + { + var stream = HandleContext.GetTarget(handle); + stream.OnAllocateCallback(out buf); + } + } +} diff --git a/src/DotNetty.NetUV/Handles/Tcp.cs b/src/DotNetty.Transport.Libuv/Handles/Tcp.cs similarity index 61% rename from src/DotNetty.NetUV/Handles/Tcp.cs rename to src/DotNetty.Transport.Libuv/Handles/Tcp.cs index 19cab5e1c..a0765fd9e 100644 --- a/src/DotNetty.NetUV/Handles/Tcp.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Tcp.cs @@ -12,18 +12,16 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Net; - using DotNetty.Buffers; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; - public sealed class Tcp : ServerStream + public sealed class Tcp : ServerStream { - internal Tcp(LoopContext loop) - : base(loop, uv_handle_type.UV_TCP) - { } + internal Tcp(LoopContext loop, uint flags = 0u /* AF_UNSPEC */) + : base(loop, uv_handle_type.UV_TCP, flags) { } public int GetSendBufferSize() => SendBufferSize(0); @@ -44,62 +42,6 @@ public int SetReceiveBufferSize(int value) return ReceiveBufferSize(value); } - public void Shutdown(Action completedAction = null) => - base.Shutdown((state, error) => completedAction?.Invoke((Tcp)state, error)); - - public void QueueWrite(byte[] array, Action completion = null) - { - if (array is null) { return; } - QueueWrite(array, 0, array.Length, completion); - } - - public void QueueWrite(byte[] array, int offset, int count, Action completion = null) - { - if (array is null || 0u >= (uint)array.Length) { return; } - if ((uint)count > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); } - if ((uint)(offset + count) > (uint)array.Length) { ThrowHelper.ThrowArgumentException_InvalidOffLen(); } - - QueueWriteStream(array, offset, count, - (state, error) => completion?.Invoke((Tcp)state, error)); - } - - public void QueueWriteStream(WritableBuffer writableBuffer, Action completion) => - base.QueueWriteStream(writableBuffer, (streamHandle, exception) => completion((Tcp)streamHandle, exception)); - - public Tcp OnRead( - Action onAccept, - Action onError, - Action onCompleted = null) - { - if (onAccept is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onAccept); } - if (onError is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onError); } - - base.OnRead( - (stream, buffer) => onAccept((Tcp)stream, buffer), - (stream, error) => onError((Tcp)stream, error), - stream => onCompleted?.Invoke((Tcp)stream)); - - return this; - } - - public Tcp OnRead(Action onRead) - { - if (onRead is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onRead); } - - base.OnRead((stream, completion) => onRead((Tcp)stream, completion)); - return this; - } - - public Tcp Bind(IPEndPoint endPoint, bool dualStack = false) - { - if (endPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.endPoint); } - - Validate(); - NativeMethods.TcpBind(InternalHandle, endPoint, dualStack); - - return this; - } - public IPEndPoint GetLocalEndPoint() { Validate(); @@ -136,7 +78,33 @@ public Tcp SimultaneousAccepts(bool value) return this; } - protected internal override unsafe StreamHandle NewStream() + public void QueueWrite(byte[] array, Action completion = null) + { + if (array is null) { return; } + QueueWrite(array, 0, array.Length, completion); + } + + public void QueueWrite(byte[] array, int offset, int count, Action completion = null) + { + if (array is null || 0u >= (uint)array.Length) { return; } + if ((uint)count > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); } + if ((uint)(offset + count) > (uint)array.Length) { ThrowHelper.ThrowArgumentException_InvalidOffLen(); } + + QueueWriteStream(array, offset, count, + (state, error) => completion?.Invoke(state, error)); + } + + public Tcp Bind(IPEndPoint endPoint, bool dualStack = false) + { + if (endPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.endPoint); } + + Validate(); + NativeMethods.TcpBind(InternalHandle, endPoint, dualStack); + + return this; + } + + internal override unsafe IInternalStreamHandle NewStream() { IntPtr loopHandle = ((uv_stream_t*)InternalHandle)->loop; var loop = HandleContext.GetTarget(loopHandle); @@ -158,22 +126,8 @@ protected internal override unsafe StreamHandle NewStream() public Tcp Listen(Action onConnection, int backlog = DefaultBacklog) { - if (onConnection is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onConnection); } - if ((uint)(backlog - 1) > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_Positive(backlog, ExceptionArgument.backlog); } - - StreamListen((handle, exception) => onConnection((Tcp)handle, exception), backlog); + StreamListen(onConnection, backlog); return this; } - - public void CloseHandle(Action onClosed = null) - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((Tcp)state); - } - - base.CloseHandle(handler); - } } } diff --git a/src/DotNetty.NetUV/Handles/Timer.cs b/src/DotNetty.Transport.Libuv/Handles/Timer.cs similarity index 61% rename from src/DotNetty.NetUV/Handles/Timer.cs rename to src/DotNetty.Transport.Libuv/Handles/Timer.cs index c62f5e36b..1bb5208d1 100644 --- a/src/DotNetty.NetUV/Handles/Timer.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Timer.cs @@ -12,34 +12,68 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Diagnostics.Contracts; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; /// /// Timer handles are used to schedule callbacks to be called in the future. /// - public sealed class Timer : WorkHandle + public sealed class Timer : WorkHandle { internal Timer(LoopContext loop) : base(loop, uv_handle_type.UV_TIMER) { } - public Timer Start(Action callback, long timeout, long repeat) + internal Timer(LoopContext loop, Action callback) + : base(loop, uv_handle_type.UV_TIMER) + { + if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + Callback = (h, s) => callback(h); + State = null; + } + + internal Timer(LoopContext loop, Action callback, object state) + : base(loop, uv_handle_type.UV_TIMER) { if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + Callback = callback; + State = state; + } + + public Timer Start(long timeout, long repeat) + { if ((ulong)repeat > SharedConstants.TooBigOrNegative64) { ThrowHelper.ThrowArgumentException_PositiveOrZero(repeat, ExceptionArgument.repeat); } if ((ulong)timeout > SharedConstants.TooBigOrNegative64) { ThrowHelper.ThrowArgumentException_PositiveOrZero(timeout, ExceptionArgument.timeout); } Validate(); - Callback = state => callback((Timer)state); NativeMethods.Start(InternalHandle, timeout, repeat); return this; } + public Timer Start(Action callback, long timeout, long repeat) + { + if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + + Callback = (h, s) => callback(h); + State = null; + + return Start(timeout, repeat); + } + + public Timer Start(Action callback, object state, long timeout, long repeat) + { + if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + + Callback = callback; + State = state; + + return Start(timeout, repeat); + } + public Timer SetRepeat(long repeat) { if ((ulong)repeat > SharedConstants.TooBigOrNegative64) { ThrowHelper.ThrowArgumentException_PositiveOrZero(repeat, ExceptionArgument.repeat); } @@ -65,8 +99,5 @@ public Timer Again() } public void Stop() => StopHandle(); - - public void CloseHandle(Action onClosed = null) => - base.CloseHandle(onClosed); } } diff --git a/src/DotNetty.NetUV/Handles/Tty.cs b/src/DotNetty.Transport.Libuv/Handles/Tty.cs similarity index 59% rename from src/DotNetty.NetUV/Handles/Tty.cs rename to src/DotNetty.Transport.Libuv/Handles/Tty.cs index 946a29134..e6097ca34 100644 --- a/src/DotNetty.NetUV/Handles/Tty.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Tty.cs @@ -12,11 +12,12 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using DotNetty.Buffers; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Native; public enum TtyType { @@ -36,7 +37,7 @@ public enum TtyMode IO } - public sealed class Tty : StreamHandle + public sealed class Tty : StreamHandle { private readonly TtyType _ttyType; @@ -46,43 +47,26 @@ internal Tty(LoopContext loop, TtyType ttyType) _ttyType = ttyType; } - public Tty OnRead( - Action onAccept, - Action onError, - Action onCompleted = null) + public override void OnRead(Action onAccept, Action onError, Action onCompleted = null) { - if (onAccept is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onAccept); } - if (onError is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onError); } - if (_ttyType != TtyType.In) { ThrowHelper.ThrowInvalidOperationException_uv_handle_type_is_not_readable(HandleType, InternalHandle, _ttyType); } - base.OnRead( - (stream, buffer) => onAccept((Tty)stream, buffer), - (stream, error) => onError((Tty)stream, error), - stream => onCompleted?.Invoke((Tty)stream)); - - return this; + base.OnRead(onAccept, onError, onCompleted); } - public Tty OnRead(Action onRead) + public override void OnRead(Action onRead) { - if (onRead is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.onRead); } - if (_ttyType != TtyType.In) { ThrowHelper.ThrowInvalidOperationException_uv_handle_type_is_not_readable(HandleType, InternalHandle, _ttyType); } - base.OnRead((stream, completion) => onRead((Tty)stream, completion)); - return this; + base.OnRead(onRead); } - public void Shutdown(Action completedAction = null) => - base.Shutdown((state, error) => completedAction?.Invoke((Tty)state, error)); - public Tty Mode(TtyMode mode) { if (mode == TtyMode.IO && !Platform.IsUnix) @@ -105,16 +89,5 @@ public Tty WindowSize(out int width, out int height) } public static void ResetMode() => NativeMethods.TtyResetMode(); - - public void CloseHandle(Action onClosed = null) - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((Tty)state); - } - - base.CloseHandle(handler); - } } } diff --git a/src/DotNetty.NetUV/Handles/Udp.cs b/src/DotNetty.Transport.Libuv/Handles/Udp.cs similarity index 97% rename from src/DotNetty.NetUV/Handles/Udp.cs rename to src/DotNetty.Transport.Libuv/Handles/Udp.cs index 26ad3e807..cd6014032 100644 --- a/src/DotNetty.NetUV/Handles/Udp.cs +++ b/src/DotNetty.Transport.Libuv/Handles/Udp.cs @@ -12,16 +12,16 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Diagnostics; using System.Net; using DotNetty.Buffers; - using DotNetty.NetUV.Native; - using DotNetty.NetUV.Requests; + using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Requests; - public sealed class Udp : ScheduleHandle + public sealed class Udp : ScheduleHandle { private const int FixedBufferSize = 2048; @@ -418,17 +418,6 @@ protected override void Close() _pendingRead.Dispose(); } - public void CloseHandle(Action onClosed = null) - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((Udp)state); - } - - base.CloseHandle(handler); - } - private sealed class DatagramReadCompletion : ReadCompletion, IDatagramReadCompletion { internal DatagramReadCompletion(ref ReadableBuffer data, Exception error, IPEndPoint remoteEndPoint) diff --git a/src/DotNetty.NetUV/Handles/WorkHandle.cs b/src/DotNetty.Transport.Libuv/Handles/WorkHandle (Of T).cs similarity index 53% rename from src/DotNetty.NetUV/Handles/WorkHandle.cs rename to src/DotNetty.Transport.Libuv/Handles/WorkHandle (Of T).cs index a003c565c..e3305a303 100644 --- a/src/DotNetty.NetUV/Handles/WorkHandle.cs +++ b/src/DotNetty.Transport.Libuv/Handles/WorkHandle (Of T).cs @@ -12,35 +12,45 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; - public class WorkHandle : ScheduleHandle + public abstract class WorkHandle : ScheduleHandle, IWorkHandle + where THandle : WorkHandle { - internal static readonly uv_work_cb WorkCallback = h => OnWorkCallback(h); - protected Action Callback; + protected Action Callback; + protected object State; - internal WorkHandle( - LoopContext loop, - uv_handle_type handleType, - params object[] args) + internal WorkHandle(LoopContext loop, uv_handle_type handleType, params object[] args) : base(loop, handleType, args) { } - protected void ScheduleStart(Action callback) + protected void ScheduleStart(Action callback) + { + if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } + + ScheduleStart((h, s) => callback(h), null); + } + + protected void ScheduleStart(Action callback, object state) { if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } Validate(); Callback = callback; + State = state; NativeMethods.Start(HandleType, InternalHandle); } - protected override void Close() => Callback = null; + protected override void Close() + { + Callback = null; + State = null; + } - private void OnWorkCallback() + void IWorkHandle.OnWorkCallback() { #if DEBUG if (Log.TraceEnabled) @@ -51,7 +61,7 @@ private void OnWorkCallback() try { - Callback?.Invoke(this); + Callback?.Invoke((THandle)this, State); } catch (Exception exception) { @@ -59,23 +69,5 @@ private void OnWorkCallback() throw; } } - - private static void OnWorkCallback(IntPtr handle) - { - var workHandle = HandleContext.GetTarget(handle); - workHandle?.OnWorkCallback(); - } - - protected void CloseHandle(Action onClosed = null) - where T : WorkHandle - { - Action handler = null; - if (onClosed is object) - { - handler = state => onClosed((T)state); - } - - base.CloseHandle(handler); - } } } diff --git a/src/DotNetty.Transport.Libuv/Handles/WorkHandle.cs b/src/DotNetty.Transport.Libuv/Handles/WorkHandle.cs new file mode 100644 index 000000000..ca3936837 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Handles/WorkHandle.cs @@ -0,0 +1,30 @@ +/* + * Copyright (c) Johnny Z. All rights reserved. + * + * https://github.com/StormHub/NetUV + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) + * + * https://github.com/cuteant/dotnetty-span-fork + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +namespace DotNetty.Transport.Libuv.Handles +{ + using System; + using DotNetty.Transport.Libuv.Native; + + internal static class WorkHandle + { + internal static readonly uv_work_cb WorkCallback = h => OnWorkCallback(h); + + private static void OnWorkCallback(IntPtr handle) + { + var workHandle = HandleContext.GetTarget(handle); + workHandle?.OnWorkCallback(); + } + } +} diff --git a/src/DotNetty.Transport.Libuv/INativeChannel.cs b/src/DotNetty.Transport.Libuv/INativeChannel.cs index f1c02009e..ce8fc072d 100644 --- a/src/DotNetty.Transport.Libuv/INativeChannel.cs +++ b/src/DotNetty.Transport.Libuv/INativeChannel.cs @@ -22,13 +22,14 @@ using System; using DotNetty.Transport.Channels; -using DotNetty.Transport.Libuv.Native; +using DotNetty.Transport.Libuv.Handles; namespace DotNetty.Transport.Libuv { interface INativeChannel : IChannel { bool IsBound { get; } - NativeHandle GetHandle(); + + IInternalScheduleHandle GetHandle(); } } diff --git a/src/DotNetty.Transport.Libuv/Native/PlatformApi.Extensions.cs b/src/DotNetty.Transport.Libuv/INativeChannelUnsafe.cs similarity index 58% rename from src/DotNetty.Transport.Libuv/Native/PlatformApi.Extensions.cs rename to src/DotNetty.Transport.Libuv/INativeChannelUnsafe.cs index 11df902a9..0676c0607 100644 --- a/src/DotNetty.Transport.Libuv/Native/PlatformApi.Extensions.cs +++ b/src/DotNetty.Transport.Libuv/INativeChannelUnsafe.cs @@ -20,23 +20,30 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.Transport.Libuv.Native -{ - using System.Runtime.InteropServices; +using System; +using DotNetty.Transport.Channels; +using DotNetty.Transport.Libuv.Handles; +using DotNetty.Transport.Libuv.Native; - partial class PlatformApi +namespace DotNetty.Transport.Libuv +{ + interface INativeChannelUnsafe : IChannelUnsafe { - public static readonly bool IsWindows; + IScheduleHandle UnsafeHandle { get; } + + void FinishConnect(Tcp tcp, OperationException error); + + uv_buf_t PrepareRead(ReadOperation readOperation); - public static readonly bool IsLinux; + void FinishRead(ReadOperation readOperation); - public static readonly bool IsDarwin; + void FinishWrite(int bytesWritten, OperationException error); + } + + internal interface IServerNativeUnsafe + { + void Accept(RemoteConnection connection); - static PlatformApi() - { - IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); - IsDarwin = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); - } + void Accept(Tcp handle); } } diff --git a/src/DotNetty.Transport.Libuv/ITcpChannelFactory.cs b/src/DotNetty.Transport.Libuv/ITcpChannelFactory.cs index 63326beb0..0c0517bd5 100644 --- a/src/DotNetty.Transport.Libuv/ITcpChannelFactory.cs +++ b/src/DotNetty.Transport.Libuv/ITcpChannelFactory.cs @@ -21,8 +21,7 @@ */ using DotNetty.Transport.Channels; -using DotNetty.Transport.Channels.Sockets; -using DotNetty.Transport.Libuv.Native; +using DotNetty.Transport.Libuv.Handles; namespace DotNetty.Transport.Libuv { diff --git a/src/DotNetty.Transport.Libuv/Internal/LoggingExtensions.cs b/src/DotNetty.Transport.Libuv/Internal/LoggingExtensions.cs index 0593d6c51..481069838 100644 --- a/src/DotNetty.Transport.Libuv/Internal/LoggingExtensions.cs +++ b/src/DotNetty.Transport.Libuv/Internal/LoggingExtensions.cs @@ -22,126 +22,163 @@ using System; using System.Runtime.CompilerServices; +using DotNetty.Buffers; using DotNetty.Common.Concurrency; using DotNetty.Common.Internal.Logging; +using DotNetty.Transport.Libuv.Handles; using DotNetty.Transport.Libuv.Native; +using DotNetty.Transport.Libuv.Requests; namespace DotNetty.Transport.Libuv { - internal static class LibuvLoggingExtensions + internal static partial class LibuvLoggingExtensions { + #region -- Debug -- + [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopWalkingHandles(this IInternalLogger logger, IntPtr handle, int count) + public static void LoopDisposing(this IInternalLogger logger, IDisposable handle) { - logger.Debug($"Loop {handle} walking handles, count = {count}."); + logger.Debug("Disposing {}", handle.GetType()); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopRunningDefaultToCallCloseCallbacks(this IInternalLogger logger, IntPtr handle, int count) + public static void FailedToCloseChannelCleanly(this IInternalLogger logger, object channelObject, Exception ex) { - logger.Debug($"Loop {handle} running default to call close callbacks, count = {count}."); + logger.Debug($"Failed to close channel {channelObject} cleanly.", ex); } + #endregion + + #region -- Info -- + [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopCloseResult(this IInternalLogger logger, IntPtr handle, int result, int count) + public static void HandleAllocated(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle) { - logger.Debug($"Loop {handle} close result = {result}, count = {count}."); + logger.Info("{} {} allocated.", handleType, handle); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopCloseAllHandlesLimit20TimesExceeded(this IInternalLogger logger, IntPtr handle) + public static void HandleClosedReleasingResourcesPending(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle) { - logger.Warn($"Loop {handle} close all handles limit 20 times exceeded."); + logger.Info("{} {} closed, releasing resources pending.", handleType, handle); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopWalkCallbackDisposed(this IInternalLogger logger, IntPtr loopHandle, IntPtr handle, IDisposable target) + { + logger.Info($"Loop {loopHandle} walk callback disposed {handle} {target?.GetType()}"); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopClosed(this IInternalLogger logger, IntPtr handle, int count) + public static void Loop_memory_released(this IInternalLogger logger, IntPtr handle) { - logger.Info($"Loop {handle} closed, count = {count}."); + logger.Info($"Loop {handle} memory released."); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopGCHandleReleased(this IInternalLogger logger, IntPtr handle) + public static void Loop_GCHandle_released(this IInternalLogger logger, IntPtr handle) { logger.Info($"Loop {handle} GCHandle released."); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopMemoryReleased(this IInternalLogger logger, IntPtr handle) + public static void Loop_closed(this IInternalLogger logger, IntPtr handle) { - logger.Info($"Loop {handle} memory released."); + logger.Info($"Loop {handle} closed."); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopWalkCallbackDisposed(this IInternalLogger logger, IntPtr handle, IntPtr loopHandle, IDisposable target) + public static void Loop_allocated(this IInternalLogger logger, IntPtr handle) { - logger.Debug($"Loop {loopHandle} walk callback disposed {handle} {target?.GetType()}"); + logger.Info($"Loop {handle} allocated."); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopWalkCallbackAttemptToCloseHandleFailed(this IInternalLogger logger, IntPtr handle, IntPtr loopHandle, Exception exception) + public static void LoopThreadFinished(this IInternalLogger logger, XThread thread) { - logger.Warn($"Loop {loopHandle} Walk callback attempt to close handle {handle} failed. {exception}"); + logger.Info("Loop {}: thread finished.", thread.Name); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void FailedToCloseChannelCleanly(this IInternalLogger logger, object channelObject, Exception ex) + public static void LoopDisposed(this IInternalLogger logger, XThread thread) { - logger.Debug($"Failed to close channel {channelObject} cleanly.", ex); + logger.Info("{}:disposed.", thread.Name); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopAllocated(this IInternalLogger logger, IntPtr handle) + public static void AcceptClientConnectionFailed(this IInternalLogger logger, Exception ex) { - logger.Info($"Loop {handle} allocated."); + logger.Info("Accept client connection failed.", ex); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ListeningOnPipe(this IInternalLogger logger, int loopThreadId, string pipeName) + public static void FailedToConnectToDispatcher(this IInternalLogger logger, int retryCount, OperationException error) { - logger.Info("{} ({}) listening on pipe {}.", nameof(DispatcherEventLoop), loopThreadId, pipeName); + logger.Info($"{nameof(WorkerEventLoop)} failed to connect to dispatcher, Retry count = {retryCount}", error); } + #endregion + + #region -- Warn -- + [MethodImpl(MethodImplOptions.NoInlining)] - public static void DispatcherPipeConnected(this IInternalLogger logger, int loopThreadId, string pipeName) + public static void Handle_receive_result_truncated(this IInternalLogger logger, IntPtr handle, IByteBuffer byteBuffer) { - logger.Info($"{nameof(WorkerEventLoop)} ({loopThreadId}) dispatcher pipe {pipeName} connected."); + logger.Warn($"{uv_handle_type.UV_UDP} {handle} receive result truncated, buffer size = {byteBuffer.Capacity}"); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopThreadFinished(this IInternalLogger logger, XThread thread, IntPtr handle) + public static void Udp_Exception_whilst_invoking_read_callback(this IInternalLogger logger, Exception exception) { - logger.Info("Loop {}:{} thread finished.", thread.Name, handle); + logger.Warn($"{nameof(Udp)} Exception whilst invoking read callback.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopRunDefaultError(this IInternalLogger logger, XThread thread, IntPtr handle, Exception ex) + public static void Failed_to_close_and_releasing_resources(this IInternalLogger logger, HandleContext handle, Exception exception) { - logger.Error("Loop {}:{} run default error.", thread.Name, handle, ex); + logger.Warn($"{handle} Failed to close and releasing resources.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ShuttingDownLoopError(this IInternalLogger logger, Exception ex) + public static void Failed_to_get_loop(this IInternalLogger logger, uv_handle_type handleType, Exception exception) { - logger.Error("{}: shutting down loop error", ex); + logger.Warn($"{handleType} Failed to get loop.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopDisposed(this IInternalLogger logger, XThread thread, IntPtr handle) + public static void Pipeline_Exception_whilst_invoking_read_callback(this IInternalLogger logger, Exception exception) { - logger.Info("{}:{} disposed.", thread.Name, handle); + logger.Warn($"Pipeline Exception whilst invoking read callback.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopDisposing(this IInternalLogger logger, IDisposable handle) + public static void Loop_Walk_callback_attempt_to_close_handle_failed(this IInternalLogger logger, IntPtr loopHandle, IntPtr handle, Exception exception) { - logger.Debug("Disposing {}", handle.GetType()); + logger.Warn($"Loop {loopHandle} Walk callback attempt to close handle {handle} failed.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void AcceptClientConnectionFailed(this IInternalLogger logger, Exception ex) + public static void Loop_close_all_handles_limit_20_times_exceeded(this IInternalLogger logger, IntPtr handle) { - logger.Info("Accept client connection failed.", ex); + logger.Warn($"Loop {handle} close all handles limit 20 times exceeded."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopReleaseError(this IInternalLogger logger, XThread thread, Exception ex) + { + logger.Warn("{}:release error {}", thread.Name, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopDisposeError(this IInternalLogger logger, IDisposable handle, Exception ex) + { + logger.Warn("{} dispose error {}", handle.GetType(), ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCreateConnectRequestToDispatcher(this IInternalLogger logger, Exception exception) + { + logger.Warn($"{nameof(WorkerEventLoop)} failed to create connect request to dispatcher", exception); } [MethodImpl(MethodImplOptions.NoInlining)] @@ -150,88 +187,106 @@ public static void FailedToDisposeAClientConnection(this IInternalLogger logger, logger.Warn("Failed to dispose a client connection.", ex); } + #endregion + + #region -- Error -- + [MethodImpl(MethodImplOptions.NoInlining)] - public static void FailedToConnectToDispatcher(this IInternalLogger logger, int retryCount, OperationException error) + public static void RequestType_after_callback_error(this IInternalLogger logger, uv_req_type requestType, Exception exception) { - logger.Info($"{nameof(WorkerEventLoop)} failed to connect to dispatcher, Retry count = {retryCount}", error); + logger.Error($"{requestType} after callback error", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void IPCPipeReadError(this IInternalLogger logger, OperationException error) + public static void RequestType_work_callback_error(this IInternalLogger logger, uv_req_type requestType, Exception exception) { - logger.Warn("IPC Pipe read error", error); + logger.Error($"{requestType} work callback error", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void FailedToWriteServerHandleToClient(this IInternalLogger logger, OperationException error) + public static void RequestType_OnWatcherCallback_error(this IInternalLogger logger, uv_req_type requestType, Exception exception) { - logger.Warn($"{nameof(PipeListener)} failed to write server handle to client", error); + logger.Error($"{requestType} OnWatcherCallback error.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void FailedToSendServerHandleToClient(this IInternalLogger logger, Exception ex) + public static void RequestType_OnWatcherCallback_error(this IInternalLogger logger, uv_req_type requestType, IntPtr handle, OperationException error) { - logger.Warn($"{nameof(PipeListener)} failed to send server handle to client", ex); + logger.Error($"{requestType} {handle} error : {error.ErrorCode} {error.Name}.", error); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ReadError(this IInternalLogger logger, OperationException error) + public static void UV_SHUTDOWN_callback_error(this IInternalLogger logger, Exception exception) { - logger.Warn($"{nameof(PipeListener)} read error", error); + logger.Error("UV_SHUTDOWN callback error.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void TcpHandleReadCallbcakError(this IInternalLogger logger, IntPtr handle, Exception exception) + public static void NativeHandle_error_whilst_closing_handle(this IInternalLogger logger, IntPtr handle, Exception exception) { - logger.Warn($"Tcp {handle} read callbcak error.", exception); + logger.Error($"{nameof(NativeHandle)} {handle} error whilst closing handle.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void TerminatedWithNonEmptyTaskQueue(this IInternalLogger logger, int count) + public static void Handle_callback_error(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle, Exception exception) { - logger.Warn($"{nameof(LoopExecutor)} terminated with non-empty task queue ({count})"); + logger.Error($"{handleType} {handle} callback error.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopReleaseError(this IInternalLogger logger, XThread thread, IntPtr handle, Exception ex) + public static void Handle_read_error(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle, int status, Exception exception) { - logger.Warn("{}:{} release error {}", thread.Name, handle, ex); + logger.Error($"{handleType} {handle} read error, status = {status}", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void LoopDisposeError(this IInternalLogger logger, IDisposable handle, Exception ex) + public static void Handle_faulted(this IInternalLogger logger, uv_handle_type handleType, Exception exception) { - logger.Warn("{} dispose error {}", handle.GetType(), ex); + logger.Error($"{handleType} faulted.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void FailedToCreateConnectRequestToDispatcher(this IInternalLogger logger, Exception exception) + public static void Pipeline_Handle_faulted(this IInternalLogger logger, uv_handle_type handleType, Exception exception) { - logger.Warn($"{nameof(WorkerEventLoop)} failed to create connect request to dispatcher", exception); + logger.Error($"Pipeline {handleType} faulted.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void FailedToConnectToDispatcher(this IInternalLogger logger, ConnectRequest request) + public static void Handle_close_handle_callback_error(this IInternalLogger logger, uv_handle_type handleType, Exception exception) { - logger.Warn($"{nameof(WorkerEventLoop)} failed to connect to dispatcher", request.Error); + logger.Error($"{handleType} close handle callback error.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void CallbackRrror(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle, Exception exception) + public static void Failed_to_close_handle(this IInternalLogger logger, uv_handle_type handleType, Exception exception) { - logger.Error($"{handleType} {handle} callback error.", exception); + logger.Error($"{handleType} Failed to close handle.", exception); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ErrorWhilstClosingHandle(this IInternalLogger logger, uv_req_type requestType, IntPtr handle, Exception exception) + public static void Handle_failed_to_shutdown(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle, Exception error) { - logger.Error($"{requestType} {handle} error whilst closing handle.", exception); + logger.Error($"{handleType} {handle} failed to shutdown.", error); } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ErrorWhilstClosingHandle(this IInternalLogger logger, IntPtr handle, Exception exception) + public static void Failed_to_write_data(this IInternalLogger logger, uv_handle_type handleType, WriteRequest request, Exception exception) { - logger.Error($"{nameof(NativeHandle)} {handle} error whilst closing handle.", exception); + logger.Error($"{handleType} Failed to write data {request}.", exception); } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopRunDefaultError(this IInternalLogger logger, XThread thread, Exception ex) + { + logger.Error("Loop {}:run default error.", thread.Name, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ShuttingDownLoopError(this IInternalLogger logger, Exception ex) + { + logger.Error("{}: shutting down loop error", ex); + } + + #endregion } } diff --git a/src/DotNetty.Transport.Libuv/Internal/Strings.Designer.cs b/src/DotNetty.Transport.Libuv/Internal/Strings.Designer.cs index e40378097..d7eda19d8 100644 --- a/src/DotNetty.Transport.Libuv/Internal/Strings.Designer.cs +++ b/src/DotNetty.Transport.Libuv/Internal/Strings.Designer.cs @@ -19,7 +19,7 @@ namespace DotNetty.Transport.Libuv.Internal { // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Strings { @@ -47,8 +47,8 @@ internal Strings() { } /// - /// 使用此强类型资源类,为所有资源查找 - /// 重写当前线程的 CurrentUICulture 属性。 + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { diff --git a/src/DotNetty.Transport.Libuv/Internal/ThrowHelper.Extensions.cs b/src/DotNetty.Transport.Libuv/Internal/ThrowHelper.Extensions.cs index cfaf38da7..c830cbd02 100644 --- a/src/DotNetty.Transport.Libuv/Internal/ThrowHelper.Extensions.cs +++ b/src/DotNetty.Transport.Libuv/Internal/ThrowHelper.Extensions.cs @@ -26,9 +26,9 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading.Tasks; -using DotNetty.Common.Concurrency; using DotNetty.Common.Utilities; using DotNetty.Transport.Channels; +using DotNetty.Transport.Libuv.Handles; using DotNetty.Transport.Libuv.Native; namespace DotNetty.Transport.Libuv @@ -48,6 +48,8 @@ internal enum ExceptionArgument key, obj, str, + tcp, + udp, list, pool, @@ -56,6 +58,10 @@ internal enum ExceptionArgument item, type, func, + loop, + pipe, + size, + node, task, match, @@ -67,7 +73,10 @@ internal enum ExceptionArgument index, count, + action, policy, + handle, + repeat, offset, method, buffer, @@ -75,22 +84,38 @@ internal enum ExceptionArgument values, parent, length, + onRead, + socket, target, member, + buffers, + backlog, feature, manager, newSize, invoker, options, + minimum, + initial, + maximum, + onError, + service, + timeout, assembly, capacity, + endPoint, fullName, typeInfo, typeName, nThreads, + onAccept, + pipeName, + callback, + interval, + allocator, defaultFn, fieldInfo, predicate, @@ -100,6 +125,10 @@ internal enum ExceptionArgument collection, expression, startIndex, + remoteName, + readAction, + completion, + sendHandle, directories, dirEnumArgs, @@ -108,12 +137,24 @@ internal enum ExceptionArgument valueFactory, propertyInfo, instanceType, + workCallback, + streamHandle, + onConnection, attributeType, + channelUnsafe, + localEndPoint, + receiveAction, chooserFactory, eventLoopGroup, parameterTypes, + remoteEndPoint, + + connectedAction, + + multicastAddress, + interfaceAddress, assemblyPredicate, qualifiedTypeName, @@ -132,7 +173,7 @@ internal enum ExceptionResource #endregion - partial class ThrowHelper + internal partial class ThrowHelper { #region -- ArgumentException -- @@ -177,9 +218,39 @@ ArgumentException GetException() } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowArgumentException_RegChannel() + internal static int ThrowArgumentException_PositiveOrOne(int value, ExceptionArgument argument) { - throw GetArgumentException(); + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"{GetArgumentName(argument)}: {value} (expected: >= 1)"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_InvalidOffLen() + { + throw GetException(); + static ArgumentException GetException() + { + return new ArgumentException("Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_TtyMode_is_Unix_only(TtyMode mode) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"{mode} is Unix only.", nameof(mode)); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task FromArgumentException_RegChannel() + { + return TaskUtil.FromException(GetArgumentException()); static ArgumentException GetArgumentException() { @@ -203,130 +274,130 @@ static ArgumentException GetArgumentException() #region -- InvalidOperationException -- [MethodImpl(MethodImplOptions.NoInlining)] - internal static Task ThrowInvalidOperationException(IntPtr loopHandle) + internal static InvalidOperationException GetInvalidOperationException_uv_handle_type_not_supported_or_IPC_over_Pipe_is_disabled(uv_handle_type handleType) { - throw GetInvalidOperationException(); - InvalidOperationException GetInvalidOperationException() - { - return new InvalidOperationException($"Loop {loopHandle} does not exist"); - } + return new InvalidOperationException($"{handleType} not supported or IPC over Pipe is disabled."); } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_ExecutionState(int executionState) + internal static InvalidOperationException GetInvalidOperationException_Pipe_IPC_handle_not_supported(uv_handle_type type) { - throw GetInvalidOperationException(); - InvalidOperationException GetInvalidOperationException() - { - return new InvalidOperationException($"Invalid state {executionState}"); - } + return new InvalidOperationException($"Pipe IPC handle {type} not supported"); } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_ExecutionState0(int executionState) + internal static void ThrowInvalidOperationException_TcpHandle() { throw GetInvalidOperationException(); - InvalidOperationException GetInvalidOperationException() + + static InvalidOperationException GetInvalidOperationException() { - return new InvalidOperationException($"Invalid {nameof(LoopExecutor)} state {executionState}"); + return new InvalidOperationException("Tcp handle not intialized"); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_ExpectingTcpHandle(uv_handle_type type) + internal static void ThrowInvalidOperationException_HandleNotInit() { throw GetInvalidOperationException(); - InvalidOperationException GetInvalidOperationException() + + static InvalidOperationException GetInvalidOperationException() { - return new InvalidOperationException($"Expecting tcp handle, {type} not supported"); + return new InvalidOperationException("tcpListener handle not intialized"); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_Dispatch() + internal static void ThrowInvalidOperationException_Udp_data_handler_has_already_been_registered() { - throw GetInvalidOperationException(); - - static InvalidOperationException GetInvalidOperationException() + throw GetException(); + static InvalidOperationException GetException() { - return new InvalidOperationException("No pipe connections to dispatch handles."); + return new InvalidOperationException( + $"{nameof(Udp)} data handler has already been registered"); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_ConnAttempt() + internal static void ThrowInvalidOperationException_ExecutionState(int executionState) { throw GetInvalidOperationException(); - - static InvalidOperationException GetInvalidOperationException() + InvalidOperationException GetInvalidOperationException() { - return new InvalidOperationException("connection attempt already made"); + return new InvalidOperationException($"Invalid state {executionState}"); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_TcpHandle() + internal static void ThrowInvalidOperationException_ExecutionState0(int executionState) { throw GetInvalidOperationException(); - - static InvalidOperationException GetInvalidOperationException() + InvalidOperationException GetInvalidOperationException() { - return new InvalidOperationException("Tcp handle not intialized"); + return new InvalidOperationException($"Invalid {nameof(AbstractUVEventLoop)} state {executionState}"); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal static uint ThrowInvalidOperationException_Dispatch(AddressFamily addressFamily) + internal static void ThrowInvalidOperationException_uv_handle_type_is_not_readable(uv_handle_type handleType, IntPtr internalHandle, TtyType ttyType) { - throw GetInvalidOperationException(); - InvalidOperationException GetInvalidOperationException() + throw GetException(); + InvalidOperationException GetException() { - return new InvalidOperationException($"Address family : {addressFamily} platform : {RuntimeInformation.OSDescription} not supported"); + return new InvalidOperationException( + $"{handleType} {internalHandle} mode {ttyType} is not readable"); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_FailedToCreateChildEventLoop(Exception ex) + internal static Task FromInvalidOperationException(IntPtr loopHandle) { - throw GetInvalidOperationException(); + return TaskUtil.FromException(GetInvalidOperationException()); InvalidOperationException GetInvalidOperationException() { - return new InvalidOperationException("failed to create a child event loop.", ex); + return new InvalidOperationException($"Loop {loopHandle} does not exist"); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_CreateChild(Exception ex) + internal static void ThrowInvalidOperationException_Dispatch() { throw GetInvalidOperationException(); - InvalidOperationException GetInvalidOperationException() + + static InvalidOperationException GetInvalidOperationException() { - return new InvalidOperationException($"Failed to create a child {nameof(WorkerEventLoop)}.", ex.Unwrap()); + return new InvalidOperationException("No pipe connections to dispatch handles."); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowInvalidOperationException_HandleNotInit() + internal static void ThrowInvalidOperationException_ConnAttempt() { throw GetInvalidOperationException(); static InvalidOperationException GetInvalidOperationException() { - return new InvalidOperationException("tcpListener handle not intialized"); + return new InvalidOperationException("connection attempt already made"); } } - #endregion - - #region -- SocketException -- + [MethodImpl(MethodImplOptions.NoInlining)] + internal static uint FromInvalidOperationException_Dispatch(AddressFamily addressFamily) + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException($"Address family : {addressFamily} platform : {RuntimeInformation.OSDescription} not supported"); + } + } [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowSocketException(int errorCode) + internal static void ThrowInvalidOperationException_CreateChild(Exception ex) { - throw GetSocketException(); - SocketException GetSocketException() + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() { - return new SocketException(errorCode); + return new InvalidOperationException($"Failed to create a child {nameof(WorkerEventLoop)}.", ex.Unwrap()); } } @@ -366,32 +437,72 @@ ChannelException GetChannelException() #endregion - #region -- TimeoutException -- + #region -- NotSupportedException -- [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowTimeoutException(string pipeName) + internal static NotSupportedException GetNotSupportedException_Poll_argument_must_be_either_IntPtr_or_int() + { + return new NotSupportedException("Poll argument must be either IntPtr or int"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static NotSupportedException GetNotSupportedException_expecting_InterNetworkkV6OrV4(IPEndPoint endPoint) + { + return new NotSupportedException( + $"End point {endPoint} is not supported, expecting InterNetwork/InterNetworkV6."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static NotSupportedException GetNotSupportedException_Handle_type_to_initialize_not_supported(uv_handle_type handleType) + { + return new NotSupportedException($"Handle type to initialize {handleType} not supported"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static NotSupportedException GetNotSupportedException_Handle_type_to_start_not_supported(uv_handle_type handleType) + { + return new NotSupportedException($"Handle type to start {handleType} not supported"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static NotSupportedException GetNotSupportedException_Handle_type_to_stop_not_supported(uv_handle_type handleType) + { + return new NotSupportedException($"Handle type to stop {handleType} not supported"); + } + + #endregion + + #region -- PlatformNotSupportedException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowPlatformNotSupportedException_handle_type_send_buffer_size_setting_not_supported_on_Windows(uv_handle_type handleType) { throw GetException(); - TimeoutException GetException() + PlatformNotSupportedException GetException() { - return new TimeoutException($"Connect to dispatcher pipe {pipeName} timed out."); + return new PlatformNotSupportedException($"{handleType} send buffer size setting not supported on Windows"); } } #endregion - #region -- NotSupportedException -- + #region -- SocketException -- [MethodImpl(MethodImplOptions.NoInlining)] - internal static NotSupportedException GetNotSupportedException(IPEndPoint endPoint) + internal static void ThrowSocketException(int errorCode) { - return new NotSupportedException($"End point {endPoint} is not supported, expecting InterNetwork/InterNetworkV6."); + throw GetSocketException(); + SocketException GetSocketException() + { + return new SocketException(errorCode); + } } #endregion #region -- ConnectTimeoutException -- + [MethodImpl(MethodImplOptions.NoInlining)] internal static ConnectTimeoutException GetConnectTimeoutException(OperationException error) { return new ConnectTimeoutException(error.ToString()); @@ -399,6 +510,20 @@ internal static ConnectTimeoutException GetConnectTimeoutException(OperationExce #endregion + #region -- TimeoutException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowTimeoutException(string pipeName) + { + throw GetException(); + TimeoutException GetException() + { + return new TimeoutException($"Connect to dispatcher pipe {pipeName} timed out."); + } + } + + #endregion + #region -- ClosedChannelException -- internal static ClosedChannelException GetClosedChannelException() diff --git a/src/DotNetty.Transport.Libuv/Native/Async.cs b/src/DotNetty.Transport.Libuv/Native/Async.cs deleted file mode 100644 index fb9c12d2e..000000000 --- a/src/DotNetty.Transport.Libuv/Native/Async.cs +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Diagnostics; - using System.Runtime.InteropServices; - - sealed unsafe class Async : NativeHandle - { - static readonly uv_work_cb WorkCallback = h => OnWorkCallback(h); - - readonly Action _callback; - readonly object _state; - - public Async(Loop loop, Action callback, object state) - : base(uv_handle_type.UV_ASYNC) - { - Debug.Assert(loop is object); - Debug.Assert(callback is object); - - IntPtr handle = NativeMethods.Allocate(uv_handle_type.UV_ASYNC); - try - { - int result = NativeMethods.uv_async_init(loop.Handle, handle, WorkCallback); - NativeMethods.ThrowIfError(result); - } - catch - { - NativeMethods.FreeMemory(handle); - throw; - } - - GCHandle gcHandle = GCHandle.Alloc(this, GCHandleType.Normal); - ((uv_handle_t*)handle)->data = GCHandle.ToIntPtr(gcHandle); - - Handle = handle; - _callback = callback; - _state = state; - } - - public void Send() - { - if (!IsValid) - { - return; - } - - int result = NativeMethods.uv_async_send(Handle); - NativeMethods.ThrowIfError(result); - } - - void OnWorkCallback() - { - try - { - _callback(_state); - } - catch (Exception exception) - { - Logger.CallbackRrror(HandleType, Handle, exception); - } - } - - static void OnWorkCallback(IntPtr handle) - { - var workHandle = GetTarget(handle); - workHandle?.OnWorkCallback(); - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/ErrorCode.cs b/src/DotNetty.Transport.Libuv/Native/ErrorCode.cs index aaff10235..d3f7cdbd8 100644 --- a/src/DotNetty.Transport.Libuv/Native/ErrorCode.cs +++ b/src/DotNetty.Transport.Libuv/Native/ErrorCode.cs @@ -1,19 +1,11 @@ /* - * Copyright 2012 The Netty Project + * Copyright (c) Johnny Z. All rights reserved. * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: + * https://github.com/StormHub/NetUV * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) * * https://github.com/cuteant/dotnetty-span-fork * @@ -250,4 +242,4 @@ public enum ErrorCode /// UV_EMLINK: too many links EMLINK, } -} \ No newline at end of file +} diff --git a/src/DotNetty.Transport.Libuv/Native/ErrorCodeExtensions.cs b/src/DotNetty.Transport.Libuv/Native/ErrorCodeExtensions.cs index 34a6f8379..fa57dd785 100644 --- a/src/DotNetty.Transport.Libuv/Native/ErrorCodeExtensions.cs +++ b/src/DotNetty.Transport.Libuv/Native/ErrorCodeExtensions.cs @@ -1,19 +1,11 @@ /* - * Copyright 2012 The Netty Project + * Copyright (c) Johnny Z. All rights reserved. * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: + * https://github.com/StormHub/NetUV * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) * * https://github.com/cuteant/dotnetty-span-fork * diff --git a/src/DotNetty.Transport.Libuv/Native/Loop.cs b/src/DotNetty.Transport.Libuv/Native/Loop.cs deleted file mode 100644 index f783707e6..000000000 --- a/src/DotNetty.Transport.Libuv/Native/Loop.cs +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using DotNetty.Common.Internal.Logging; - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - - sealed unsafe class Loop : IDisposable - { - private static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); - private static readonly uv_walk_cb WalkCallback = (h, s) => OnWalkCallback(h, s); - - private IntPtr _handle; - - public Loop() - { - IntPtr loopHandle = NativeMethods.Allocate(NativeMethods.uv_loop_size().ToInt32()); - try - { - int result = NativeMethods.uv_loop_init(loopHandle); - NativeMethods.ThrowIfError(result); - } - catch - { - NativeMethods.FreeMemory(loopHandle); - throw; - } - - GCHandle gcHandle = GCHandle.Alloc(this, GCHandleType.Normal); - ((uv_loop_t*)loopHandle)->data = GCHandle.ToIntPtr(gcHandle); - _handle = loopHandle; - if (Logger.InfoEnabled) - { - Logger.LoopAllocated(_handle); - } - } - - internal IntPtr Handle => _handle; - - public bool IsAlive => _handle != IntPtr.Zero && NativeMethods.uv_loop_alive(_handle) != 0; - - public void UpdateTime() - { - Validate(); - NativeMethods.uv_update_time(Handle); - } - - public long Now - { - get - { - Validate(); - return NativeMethods.uv_now(_handle); - } - } - - public long NowInHighResolution - { - get - { - Validate(); - return NativeMethods.uv_hrtime(_handle); - } - } - - public int GetBackendTimeout() - { - Validate(); - return NativeMethods.uv_backend_timeout(_handle); - } - - public int ActiveHandleCount() - { - if (_handle != IntPtr.Zero) - { - return (int)((uv_loop_t*)_handle)->active_handles; - } - return 0; - } - - public int Run(uv_run_mode mode) - { - Validate(); - return NativeMethods.uv_run(_handle, mode); - } - - public void Stop() - { - if (_handle != IntPtr.Zero) - { - NativeMethods.uv_stop(_handle); - } - } - - [MethodImpl(InlineMethod.AggressiveOptimization)] - void Validate() - { - if (_handle == IntPtr.Zero) - { - ThrowObjectDisposedException(); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowObjectDisposedException() - { - throw GetObjectDisposedException(); - - static ObjectDisposedException GetObjectDisposedException() - { - return new ObjectDisposedException($"{typeof(Loop)}"); - } - } - - public void Dispose() - { - Close(); - GC.SuppressFinalize(this); - } - - void Close() - { - IntPtr loopHandle = _handle; - Close(loopHandle); - _handle = IntPtr.Zero; - } - - static void Close(IntPtr handle) - { - if (handle == IntPtr.Zero) - { - return; - } - - // Get gc handle before close loop - IntPtr pHandle = ((uv_loop_t*)handle)->data; - - // Fully close the loop, similar to - //https://github.com/libuv/libuv/blob/v1.x/test/task.h#L190 - - int count = 0; -#if DEBUG - var debugEnabled = Logger.DebugEnabled; -#endif - while (true) - { -#if DEBUG - if (debugEnabled) Logger.LoopWalkingHandles(handle, count); -#endif - NativeMethods.uv_walk(handle, WalkCallback, handle); - -#if DEBUG - if (debugEnabled) Logger.LoopRunningDefaultToCallCloseCallbacks(handle, count); -#endif - _ = NativeMethods.uv_run(handle, uv_run_mode.UV_RUN_DEFAULT); - - int result = NativeMethods.uv_loop_close(handle); -#if DEBUG - if (debugEnabled) Logger.LoopCloseResult(handle, result, count); -#endif - if (0u >= (uint)result) - { - break; - } - - count++; - if (count >= 20) - { - Logger.LoopCloseAllHandlesLimit20TimesExceeded(handle); - break; - } - } - var infoEnabled = Logger.InfoEnabled; - if (infoEnabled) Logger.LoopClosed(handle, count); - - // Free GCHandle - if (pHandle != IntPtr.Zero) - { - GCHandle nativeHandle = GCHandle.FromIntPtr(pHandle); - if (nativeHandle.IsAllocated) - { - nativeHandle.Free(); - ((uv_loop_t*)handle)->data = IntPtr.Zero; - if (infoEnabled) Logger.LoopGCHandleReleased(handle); - } - } - - // Release memory - NativeMethods.FreeMemory(handle); - if (infoEnabled) Logger.LoopMemoryReleased(handle); - } - - static void OnWalkCallback(IntPtr handle, IntPtr loopHandle) - { - if (handle == IntPtr.Zero) - { - return; - } - - try - { - // All handles must implement IDisposable - var target = NativeHandle.GetTarget(handle); - target?.Dispose(); -#if DEBUG - if (Logger.DebugEnabled) Logger.LoopWalkCallbackDisposed(handle, loopHandle, target); -#endif - } - catch (Exception exception) - { - if (Logger.WarnEnabled) Logger.LoopWalkCallbackAttemptToCloseHandleFailed(handle, loopHandle, exception); - } - } - - ~Loop() => Close(); - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/NativeHandle.cs b/src/DotNetty.Transport.Libuv/Native/NativeHandle.cs index d3793a2a8..d655d0762 100644 --- a/src/DotNetty.Transport.Libuv/Native/NativeHandle.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeHandle.cs @@ -1,25 +1,11 @@ /* - * Copyright 2012 The Netty Project + * Copyright (c) Johnny Z. All rights reserved. * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty + * https://github.com/StormHub/NetUV * * Licensed under the MIT license. See LICENSE file in the project root for full license information. * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) * * https://github.com/cuteant/dotnetty-span-fork * @@ -28,125 +14,73 @@ namespace DotNetty.Transport.Libuv.Native { - using DotNetty.Common.Internal.Logging; using System; - using System.Diagnostics; using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; + using DotNetty.Common.Internal.Logging; - public abstract unsafe class NativeHandle : IDisposable + internal abstract class NativeHandle : IDisposable { - protected static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); - private static readonly uv_close_cb CloseCallback = h => OnCloseHandle(h); - internal readonly uv_handle_type HandleType; - internal IntPtr Handle; + protected static readonly IInternalLogger Log = InternalLoggerFactory.GetInstance(); + private IntPtr _handle; - internal NativeHandle(uv_handle_type handleType) + protected NativeHandle() { - HandleType = handleType; + _handle = IntPtr.Zero; } - internal IntPtr LoopHandle() + protected internal IntPtr Handle { - Validate(); - return ((uv_handle_t*)Handle)->loop; + [MethodImpl(InlineMethod.AggressiveOptimization)] + get => _handle; + protected set => _handle = value; } - protected bool IsValid + internal bool IsValid { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Handle != IntPtr.Zero; + [MethodImpl(InlineMethod.AggressiveOptimization)] + get => _handle != IntPtr.Zero; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected void Validate() + [MethodImpl(InlineMethod.AggressiveOptimization)] + protected internal void Validate() { - if (!IsValid) - { - ThrowObjectDisposedException(); - } + if (!IsValid) { ThrowObjectDisposedException(); } } [MethodImpl(MethodImplOptions.NoInlining)] - internal void ThrowObjectDisposedException() + private void ThrowObjectDisposedException() { throw GetObjectDisposedException(); - ObjectDisposedException GetObjectDisposedException() - { - return new ObjectDisposedException($"{GetType()}"); - } - } - - internal void RemoveReference() - { - Validate(); - NativeMethods.uv_unref(Handle); - } - - internal bool IsActive => IsValid && NativeMethods.uv_is_active(Handle) > 0; - internal void CloseHandle() - { - IntPtr handle = Handle; - if (handle == IntPtr.Zero) - { - return; - } - - int result = NativeMethods.uv_is_closing(handle); - if (0u >= (uint)result) + ObjectDisposedException GetObjectDisposedException() { - NativeMethods.uv_close(handle, CloseCallback); + return new ObjectDisposedException(GetType().FullName); } } - protected virtual void OnClosed() - { - Handle = IntPtr.Zero; - } - - static void OnCloseHandle(IntPtr handle) - { - if (handle == IntPtr.Zero) - { - return; - } + internal void SetHandleAsInvalid() => _handle = IntPtr.Zero; - NativeHandle nativeHandle = null; + protected abstract void CloseHandle(); - // Get gc handle first - IntPtr pHandle = ((uv_handle_t*)handle)->data; - if (pHandle != IntPtr.Zero) - { - GCHandle gcHandle = GCHandle.FromIntPtr(pHandle); - if (gcHandle.IsAllocated) - { - nativeHandle = gcHandle.Target as NativeHandle; - gcHandle.Free(); - - ((uv_handle_t*)handle)->data = IntPtr.Zero; - } - } - - // Release memory - NativeMethods.FreeMemory(handle); - nativeHandle?.OnClosed(); - } - - void Dispose(bool disposing) + private void Dispose(bool disposing) { try { - if (IsValid) + if (!IsValid) { return; } +#if DEBUG + if (Log.DebugEnabled) { - CloseHandle(); + Log.Debug("Disposing {} (Finalizer {})", _handle, !disposing); } +#endif + CloseHandle(); } catch (Exception exception) { - Logger.ErrorWhilstClosingHandle(Handle, exception); + Log.NativeHandle_error_whilst_closing_handle(_handle, exception); + // For finalizer, we cannot allow this to escape. - if (disposing) throw; + if (disposing) { throw; } } } @@ -156,22 +90,9 @@ public void Dispose() GC.SuppressFinalize(this); } - ~NativeHandle() => Dispose(false); - - internal static T GetTarget(IntPtr handle) + ~NativeHandle() { - Debug.Assert(handle != IntPtr.Zero); - - IntPtr inernalHandle = ((uv_handle_t*)handle)->data; - if (inernalHandle != IntPtr.Zero) - { - GCHandle gcHandle = GCHandle.FromIntPtr(inernalHandle); - if (gcHandle.IsAllocated) - { - return (T)gcHandle.Target; - } - } - return default; + Dispose(false); } } } diff --git a/src/DotNetty.NetUV/Native/NativeFiles.cs b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Files.cs similarity index 98% rename from src/DotNetty.NetUV/Native/NativeFiles.cs rename to src/DotNetty.Transport.Libuv/Native/NativeMethods.Files.cs index 0d687211b..892841074 100644 --- a/src/DotNetty.NetUV/Native/NativeFiles.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Files.cs @@ -12,12 +12,12 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Native +namespace DotNetty.Transport.Libuv.Native { using System; using System.Diagnostics; using System.Runtime.InteropServices; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; #pragma warning disable IDE1006 // 命名样式 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] diff --git a/src/DotNetty.NetUV/Native/NativeHandles.cs b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Handles.cs similarity index 87% rename from src/DotNetty.NetUV/Native/NativeHandles.cs rename to src/DotNetty.Transport.Libuv/Native/NativeMethods.Handles.cs index d76474a58..03861008b 100644 --- a/src/DotNetty.NetUV/Native/NativeHandles.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Handles.cs @@ -12,7 +12,7 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Native +namespace DotNetty.Transport.Libuv.Native { using System; using System.Diagnostics; @@ -20,8 +20,9 @@ namespace DotNetty.NetUV.Native using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Requests; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Requests; #pragma warning disable IDE1006 // 命名样式 internal enum uv_handle_type @@ -254,79 +255,71 @@ internal static partial class NativeMethods #region Common - internal static HandleContext Initialize(IntPtr loopHandle, uv_handle_type handleType, ScheduleHandle target, object[] args) + internal static HandleContext Initialize(IntPtr loopHandle, uv_handle_type handleType, IInternalScheduleHandle target, object[] args) { Debug.Assert(loopHandle != IntPtr.Zero); Debug.Assert(target is object); - switch (handleType) + return handleType switch { - case uv_handle_type.UV_TIMER: - return new HandleContext(handleType, InitializeTimer, loopHandle, target, args); - case uv_handle_type.UV_PREPARE: - return new HandleContext(handleType, InitializePrepare, loopHandle, target, args); - case uv_handle_type.UV_CHECK: - return new HandleContext(handleType, InitializeCheck, loopHandle, target, args); - case uv_handle_type.UV_IDLE: - return new HandleContext(handleType, InitializeIdle, loopHandle, target, args); - case uv_handle_type.UV_ASYNC: - return new HandleContext(handleType, InitializeAsync, loopHandle, target, args); - case uv_handle_type.UV_POLL: - return new HandleContext(handleType, InitializePoll, loopHandle, target, args); - case uv_handle_type.UV_SIGNAL: - return new HandleContext(handleType, InitializeSignal, loopHandle, target, args); - case uv_handle_type.UV_TCP: - return new HandleContext(handleType, InitializeTcp, loopHandle, target, args); - case uv_handle_type.UV_NAMED_PIPE: - return new HandleContext(handleType, InitializePipe, loopHandle, target, args); - case uv_handle_type.UV_TTY: - return new HandleContext(handleType, InitializeTty, loopHandle, target, args); - case uv_handle_type.UV_UDP: - return new HandleContext(handleType, InitializeUdp, loopHandle, target, args); - case uv_handle_type.UV_FS_EVENT: - return new HandleContext(handleType, InitializeFSEvent, loopHandle, target, args); - case uv_handle_type.UV_FS_POLL: - return new HandleContext(handleType, InitializeFSPoll, loopHandle, target, args); - default: - throw ThrowHelper.GetNotSupportedException_Handle_type_to_initialize_not_supported(handleType); - } + uv_handle_type.UV_TIMER => new HandleContext(handleType, s_initializeTimerFunc, loopHandle, target, args), + uv_handle_type.UV_PREPARE => new HandleContext(handleType, s_initializePrepareFunc, loopHandle, target, args), + uv_handle_type.UV_CHECK => new HandleContext(handleType, s_initializeCheckFunc, loopHandle, target, args), + uv_handle_type.UV_IDLE => new HandleContext(handleType, s_initializeIdleFunc, loopHandle, target, args), + uv_handle_type.UV_ASYNC => new HandleContext(handleType, s_initializeAsyncFunc, loopHandle, target, args), + uv_handle_type.UV_POLL => new HandleContext(handleType, s_initializePollFunc, loopHandle, target, args), + uv_handle_type.UV_SIGNAL => new HandleContext(handleType, s_initializeSignalFunc, loopHandle, target, args), + uv_handle_type.UV_TCP => new HandleContext(handleType, s_initializeTcpFunc, loopHandle, target, args), + uv_handle_type.UV_NAMED_PIPE => new HandleContext(handleType, s_initializePipeFunc, loopHandle, target, args), + uv_handle_type.UV_TTY => new HandleContext(handleType, s_initializeTtyFunc, loopHandle, target, args), + uv_handle_type.UV_UDP => new HandleContext(handleType, s_initializeUdpFunc, loopHandle, target, args), + uv_handle_type.UV_FS_EVENT => new HandleContext(handleType, s_initializeFSEventFunc, loopHandle, target, args), + uv_handle_type.UV_FS_POLL => new HandleContext(handleType, s_initializeFSPollFunc, loopHandle, target, args), + _ => throw ThrowHelper.GetNotSupportedException_Handle_type_to_initialize_not_supported(handleType), + }; } - private static int InitializeTimer(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializeTimerFunc = (lh, h, args) => InitializeTimer(lh, h/*, args*/); + private static int InitializeTimer(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); return uv_timer_init(loopHandle, handle); } - private static int InitializePrepare(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializePrepareFunc = (lh, h, args) => InitializePrepare(lh, h/*, args*/); + private static int InitializePrepare(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); return uv_prepare_init(loopHandle, handle); } - private static int InitializeCheck(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializeCheckFunc = (lh, h, args) => InitializeCheck(lh, h/*, args*/); + private static int InitializeCheck(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); return uv_check_init(loopHandle, handle); } - private static int InitializeIdle(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializeIdleFunc = (lh, h, args) => InitializeIdle(lh, h/*, args*/); + private static int InitializeIdle(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); return uv_idle_init(loopHandle, handle); } - private static int InitializeAsync(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializeAsyncFunc = (lh, h, args) => InitializeAsync(lh, h/*, args*/); + private static int InitializeAsync(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); return uv_async_init(loopHandle, handle, WorkHandle.WorkCallback); } + private static readonly Func s_initializePollFunc = (lh, h, args) => InitializePoll(lh, h, args); private static int InitializePoll(IntPtr loopHandle, IntPtr handle, object[] args) { Debug.Assert(handle != IntPtr.Zero); @@ -345,20 +338,34 @@ private static int InitializePoll(IntPtr loopHandle, IntPtr handle, object[] arg throw ThrowHelper.GetNotSupportedException_Poll_argument_must_be_either_IntPtr_or_int(); } - private static int InitializeSignal(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializeSignalFunc = (lh, h, args) => InitializeSignal(lh, h/*, args*/); + private static int InitializeSignal(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); return uv_signal_init(loopHandle, handle); } + private static readonly Func s_initializeTcpFunc = (lh, h, args) => InitializeTcp(lh, h, args); private static int InitializeTcp(IntPtr loopHandle, IntPtr handle, object[] args) { Debug.Assert(handle != IntPtr.Zero); - return uv_tcp_init(loopHandle, handle); + if (args is null || 0u >= (uint)args.Length) + { + return uv_tcp_init(loopHandle, handle); + } + else + { + uint flags = (uint)args[0]; + // if flags is specified as AF_INET or AF_INET6, Libuv + // creates the socket when tcp handle is created. + // Otherwise the socket is created when bind to an address. + return uv_tcp_init_ex(loopHandle, handle, flags); + } } + private static readonly Func s_initializePipeFunc = (lh, h, args) => InitializePipe(lh, h, args); private static int InitializePipe(IntPtr loopHandle, IntPtr handle, object[] args) { Debug.Assert(handle != IntPtr.Zero); @@ -368,6 +375,7 @@ private static int InitializePipe(IntPtr loopHandle, IntPtr handle, object[] arg return uv_pipe_init(loopHandle, handle, value ? 1 : 0); } + private static readonly Func s_initializeTtyFunc = (lh, h, args) => InitializeTty(lh, h, args); private static int InitializeTty(IntPtr loopHandle, IntPtr handle, object[] args) { Debug.Assert(handle != IntPtr.Zero); @@ -377,21 +385,24 @@ private static int InitializeTty(IntPtr loopHandle, IntPtr handle, object[] args return uv_tty_init(loopHandle, handle, (int)ttyType, ttyType == TtyType.In ? 1 : 0); } - private static int InitializeUdp(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializeUdpFunc = (lh, h, args) => InitializeUdp(lh, h/*, args*/); + private static int InitializeUdp(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); return uv_udp_init(loopHandle, handle); } - private static int InitializeFSEvent(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializeFSEventFunc = (lh, h, args) => InitializeFSEvent(lh, h/*, args*/); + private static int InitializeFSEvent(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); return uv_fs_event_init(loopHandle, handle); } - private static int InitializeFSPoll(IntPtr loopHandle, IntPtr handle, object[] args) + private static readonly Func s_initializeFSPollFunc = (lh, h, args) => InitializeFSPoll(lh, h/*, args*/); + private static int InitializeFSPoll(IntPtr loopHandle, IntPtr handle/*, object[] args*/) { Debug.Assert(handle != IntPtr.Zero); @@ -401,22 +412,13 @@ private static int InitializeFSPoll(IntPtr loopHandle, IntPtr handle, object[] a internal static void Start(uv_handle_type handleType, IntPtr handle) { Debug.Assert(handle != IntPtr.Zero); - - int result; - switch (handleType) + var result = handleType switch { - case uv_handle_type.UV_PREPARE: - result = uv_prepare_start(handle, WorkHandle.WorkCallback); - break; - case uv_handle_type.UV_CHECK: - result = uv_check_start(handle, WorkHandle.WorkCallback); - break; - case uv_handle_type.UV_IDLE: - result = uv_idle_start(handle, WorkHandle.WorkCallback); - break; - default: - throw ThrowHelper.GetNotSupportedException_Handle_type_to_start_not_supported(handleType); - } + uv_handle_type.UV_PREPARE => uv_prepare_start(handle, WorkHandle.WorkCallback), + uv_handle_type.UV_CHECK => uv_check_start(handle, WorkHandle.WorkCallback), + uv_handle_type.UV_IDLE => uv_idle_start(handle, WorkHandle.WorkCallback), + _ => throw ThrowHelper.GetNotSupportedException_Handle_type_to_start_not_supported(handleType), + }; ThrowIfError(result); } @@ -858,6 +860,9 @@ internal static IPEndPoint TcpGetPeerName(IntPtr handle) [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] private static extern int uv_tcp_init(IntPtr loopHandle, IntPtr handle); + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] + private static extern int uv_tcp_init_ex(IntPtr loopHandle, IntPtr handle, uint flags); + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] private static extern int uv_tcp_bind(IntPtr handle, ref sockaddr sockaddr, uint flags); @@ -1086,18 +1091,12 @@ internal static void GetSocketAddress(IPEndPoint endPoint, out sockaddr addr) Debug.Assert(endPoint is object); string ip = endPoint.Address.ToString(); - int result; - switch (endPoint.AddressFamily) + var result = endPoint.AddressFamily switch { - case AddressFamily.InterNetwork: - result = uv_ip4_addr(ip, endPoint.Port, out addr); - break; - case AddressFamily.InterNetworkV6: - result = uv_ip6_addr(ip, endPoint.Port, out addr); - break; - default: - throw ThrowHelper.GetNotSupportedException_expecting_InterNetworkkV6OrV4(endPoint); - } + AddressFamily.InterNetwork => uv_ip4_addr(ip, endPoint.Port, out addr), + AddressFamily.InterNetworkV6 => uv_ip6_addr(ip, endPoint.Port, out addr), + _ => throw ThrowHelper.GetNotSupportedException_expecting_InterNetworkkV6OrV4(endPoint), + }; ThrowIfError(result); } diff --git a/src/DotNetty.NetUV/Native/NativeLoop.cs b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Loop.cs similarity index 96% rename from src/DotNetty.NetUV/Native/NativeLoop.cs rename to src/DotNetty.Transport.Libuv/Native/NativeMethods.Loop.cs index 50cdb8881..98a4c68cd 100644 --- a/src/DotNetty.NetUV/Native/NativeLoop.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Loop.cs @@ -12,7 +12,7 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Native +namespace DotNetty.Transport.Libuv.Native { using System; using System.Diagnostics; @@ -43,10 +43,7 @@ internal static partial class NativeMethods { internal static int GetLoopSize() { - IntPtr value = uv_loop_size(); - int size = value.ToInt32(); - - return size; + return uv_loop_size().ToInt32(); } internal static void InitializeLoop(IntPtr handle) @@ -130,6 +127,9 @@ internal static void LoopUpdateTime(IntPtr handle) uv_update_time(handle); } + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr uv_default_loop(); + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] private static extern int uv_loop_init(IntPtr handle); diff --git a/src/DotNetty.NetUV/Native/NativeRequests.cs b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Requests.cs similarity index 98% rename from src/DotNetty.NetUV/Native/NativeRequests.cs rename to src/DotNetty.Transport.Libuv/Native/NativeMethods.Requests.cs index 9cbe64f47..d4e5ba951 100644 --- a/src/DotNetty.NetUV/Native/NativeRequests.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Requests.cs @@ -12,7 +12,7 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Native +namespace DotNetty.Transport.Libuv.Native { using System; using System.Diagnostics; @@ -20,7 +20,8 @@ namespace DotNetty.NetUV.Native using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using DotNetty.NetUV.Requests; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Requests; #pragma warning disable IDE1006 // 命名样式 internal enum uv_req_type diff --git a/src/DotNetty.NetUV/Native/NativeStreams.cs b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Streams.cs similarity index 98% rename from src/DotNetty.NetUV/Native/NativeStreams.cs rename to src/DotNetty.Transport.Libuv/Native/NativeMethods.Streams.cs index 5248df625..5cbf51bf5 100644 --- a/src/DotNetty.NetUV/Native/NativeStreams.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeMethods.Streams.cs @@ -12,14 +12,15 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Native +namespace DotNetty.Transport.Libuv.Native { using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Requests; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Requests; #pragma warning disable IDE1006 // 命名样式 [StructLayout(LayoutKind.Sequential)] diff --git a/src/DotNetty.Transport.Libuv/Native/NativeMethods.cs b/src/DotNetty.Transport.Libuv/Native/NativeMethods.cs index 97ca10827..6f15a17cd 100644 --- a/src/DotNetty.Transport.Libuv/Native/NativeMethods.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeMethods.cs @@ -1,25 +1,11 @@ /* - * Copyright 2012 The Netty Project + * Copyright (c) Johnny Z. All rights reserved. * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty + * https://github.com/StormHub/NetUV * * Licensed under the MIT license. See LICENSE file in the project root for full license information. * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) * * https://github.com/cuteant/dotnetty-span-fork * @@ -30,551 +16,195 @@ namespace DotNetty.Transport.Libuv.Native { using System; using System.Diagnostics; - using System.Net; - using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; #pragma warning disable IDE1006 // 命名样式 - enum uv_run_mode - { - UV_RUN_DEFAULT = 0, - UV_RUN_ONCE, - UV_RUN_NOWAIT - }; - - [StructLayout(LayoutKind.Sequential)] - struct uv_loop_t - { - /* User data - use this for whatever. */ - public IntPtr data; - - /* Loop reference counting. */ - public uint active_handles; - } - - enum uv_handle_type - { - UV_UNKNOWN_HANDLE = 0, - UV_ASYNC, - UV_CHECK, - UV_FS_EVENT, - UV_FS_POLL, - UV_HANDLE, - UV_IDLE, - UV_NAMED_PIPE, - UV_POLL, - UV_PREPARE, - UV_PROCESS, - UV_STREAM, - UV_TCP, - UV_TIMER, - UV_TTY, - UV_UDP, - UV_SIGNAL, - UV_FILE, - UV_HANDLE_TYPE_MAX - } - - [StructLayout(LayoutKind.Sequential)] - struct uv_handle_t - { - public IntPtr data; - public IntPtr loop; - public uv_handle_type type; - public IntPtr close_cb; - } - - [StructLayout(LayoutKind.Sequential)] - struct uv_buf_t - { - //static readonly bool isWindows = PlatformApi.IsWindows; - static readonly int Size = IntPtr.Size; - - /* - Windows - public int length; - public IntPtr data; - - Unix - public IntPtr data; - public IntPtr length; - */ - - // ReSharper disable PrivateFieldCanBeConvertedToLocalVariable - readonly IntPtr first; - readonly IntPtr second; - // ReSharper restore PrivateFieldCanBeConvertedToLocalVariable - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe void InitMemory(IntPtr buf, IntPtr memory, int length) - { - var len = (IntPtr)length; - if (PlatformApi.IsWindows) - { - *(IntPtr*)buf = len; - *(IntPtr*)(buf + Size) = memory; - } - else - { - *(IntPtr*)buf = memory; - *(IntPtr*)(buf + Size) = len; - } - } - - internal uv_buf_t(IntPtr memory, int length) - { - if (PlatformApi.IsWindows) - { - this.first = (IntPtr)length; - this.second = memory; - } - else - { - this.first = memory; - this.second = (IntPtr)length; - } - } - } - - [StructLayout(LayoutKind.Sequential)] - struct uv_stream_t - { - /* handle fields */ - public IntPtr data; - public IntPtr loop; - public uv_handle_type type; - public IntPtr close_cb; - - /* stream fields */ - public IntPtr write_queue_size; /* number of bytes queued for writing */ - public IntPtr alloc_cb; - public IntPtr read_cb; - } + #region uv_err_t - enum uv_req_type + internal enum uv_err_code { - UV_UNKNOWN_REQ = 0, - UV_REQ, - UV_CONNECT, - UV_WRITE, - UV_SHUTDOWN, - UV_UDP_SEND, - UV_FS, - UV_WORK, - UV_GETADDRINFO, - UV_GETNAMEINFO, - UV_REQ_TYPE_PRIVATE, - UV_REQ_TYPE_MAX + UV_OK = 0, + UV_E2BIG, + UV_EACCES, + UV_EADDRINUSE, + UV_EADDRNOTAVAIL, + UV_EAFNOSUPPORT, + UV_EAGAIN, + UV_EAI_ADDRFAMILY, + UV_EAI_AGAIN, + UV_EAI_BADFLAGS, + UV_EAI_BADHINTS, + UV_EAI_CANCELED, + UV_EAI_FAIL, + UV_EAI_FAMILY, + UV_EAI_MEMORY, + UV_EAI_NODATA, + UV_EAI_NONAME, + UV_EAI_OVERFLOW, + UV_EAI_PROTOCOL, + UV_EAI_SERVICE, + UV_EAI_SOCKTYPE, + UV_EALREADY, + UV_EBADF, + UV_EBUSY, + UV_ECANCELED, + UV_ECHARSET, + UV_ECONNABORTED, + UV_ECONNREFUSED, + UV_ECONNRESET, + UV_EDESTADDRREQ, + UV_EEXIST, + UV_EFAULT, + UV_EFBIG, + UV_EHOSTUNREACH, + UV_EINTR, + UV_EINVAL, + UV_EIO, + UV_EISCONN, + UV_EISDIR, + UV_ELOOP, + UV_EMFILE, + UV_EMSGSIZE, + UV_ENAMETOOLONG, + UV_ENETDOWN, + UV_ENETUNREACH, + UV_ENFILE, + UV_ENOBUFS, + UV_ENODEV, + UV_ENOENT, + UV_ENOMEM, + UV_ENONET, + UV_ENOPROTOOPT, + UV_ENOSPC, + UV_ENOSYS, + UV_ENOTCONN, + UV_ENOTDIR, + UV_ENOTEMPTY, + UV_ENOTSOCK, + UV_ENOTSUP, + UV_EPERM, + UV_EPIPE, + UV_EPROTO, + UV_EPROTONOSUPPORT, + UV_EPROTOTYPE, + UV_ERANGE, + UV_EROFS, + UV_ESHUTDOWN, + UV_ESPIPE, + UV_ESRCH, + UV_ETIMEDOUT, + UV_ETXTBSY, + UV_EXDEV, + UV_UNKNOWN, + UV_EOF = -4095, + UV_ENXIO, + UV_EMLINK, } - [StructLayout(LayoutKind.Sequential)] - struct uv_req_t - { - public IntPtr data; - public uv_req_type type; - } - - [StructLayout(LayoutKind.Sequential)] - struct uv_write_t - { - /* uv_req_t fields */ - public IntPtr data; - public uv_req_type type; - - /* uv_write_t fields */ - - // Write callback - public IntPtr cb; // uv_write_cb cb; - - // Pointer to the stream being sent using this write request. - public IntPtr send_handle; // uv_stream_t* send_handle; - - // Pointer to the stream where this write request is running. - public IntPtr handle; // uv_stream_t* handle; - } - - /// - /// https://github.com/aspnet/KestrelHttpServer/blob/master/src/Kestrel.Transport.Libuv/Internal/Networking/SockAddr.cs - /// - [StructLayout(LayoutKind.Sequential)] - struct sockaddr - { - // this type represents native memory occupied by sockaddr struct - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms740496(v=vs.85).aspx - // although the c/c++ header defines it as a 2-byte short followed by a 14-byte array, - // the simplest way to reserve the same size in c# is with four nameless long values -#pragma warning disable IDE0044 // 添加只读修饰符 - private long _field0; - private long _field1; - private long _field2; - private long _field3; -#pragma warning restore IDE0044 // 添加只读修饰符 - -#pragma warning disable IDE0060 // 删除未使用的参数 - public sockaddr(long ignored) -#pragma warning restore IDE0060 // 删除未使用的参数 - { - _field0 = _field1 = _field2 = _field3 = 0; - } - - public unsafe IPEndPoint GetIPEndPoint() - { - // The bytes are represented in network byte order. - // - // Example 1: [2001:4898:e0:391:b9ef:1124:9d3e:a354]:39179 - // - // 0000 0000 0b99 0017 => The third and fourth bytes 990B is the actual port - // 9103 e000 9848 0120 => IPv6 address is represented in the 128bit field1 and field2. - // 54a3 3e9d 2411 efb9 Read these two 64-bit long from right to left byte by byte. - // 0000 0000 0000 0010 => Scope ID 0x10 (eg [::1%16]) the first 4 bytes of field3 in host byte order. - // - // Example 2: 10.135.34.141:39178 when adopt dual-stack sockets, IPv4 is mapped to IPv6 - // - // 0000 0000 0a99 0017 => The port representation are the same - // 0000 0000 0000 0000 - // 8d22 870a ffff 0000 => IPv4 occupies the last 32 bit: 0A.87.22.8d is the actual address. - // 0000 0000 0000 0000 - // - // Example 3: 10.135.34.141:12804, not dual-stack sockets - // - // 8d22 870a fd31 0002 => sa_family == AF_INET (02) - // 0000 0000 0000 0000 - // 0000 0000 0000 0000 - // 0000 0000 0000 0000 - // - // Example 4: 127.0.0.1:52798, on a Mac OS - // - // 0100 007F 3ECE 0210 => sa_family == AF_INET (02) Note that struct sockaddr on mac use - // 0000 0000 0000 0000 the second unint8 field for sa family type - // 0000 0000 0000 0000 http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/socket.h - // 0000 0000 0000 0000 - // - // Reference: - // - Windows: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506(v=vs.85).aspx - // - Linux: https://github.com/torvalds/linux/blob/6a13feb9c82803e2b815eca72fa7a9f5561d7861/include/linux/socket.h - // - Linux (sin6_scope_id): https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/net/sunrpc/addr.c#L82 - // - Apple: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/socket.h - - // Quick calculate the port by mask the field and locate the byte 3 and byte 4 - // and then shift them to correct place to form a int. - var port = ((int)(_field0 & 0x00FF0000) >> 8) | (int)((_field0 & 0xFF000000) >> 24); - - int family = (int)_field0; - if (PlatformApi.IsDarwin) - { - // see explaination in example 4 - family >>= 8; - } - family &= 0xFF; - - if (family == 2) - { - // AF_INET => IPv4 - return new IPEndPoint(new IPAddress((_field0 >> 32) & 0xFFFFFFFF), port); - } - else if (IsIPv4MappedToIPv6()) - { - var ipv4bits = (_field2 >> 32) & 0x00000000FFFFFFFF; - return new IPEndPoint(new IPAddress(ipv4bits), port); - } - else - { - // otherwise IPv6 - var bytes = new byte[16]; - fixed (byte* b = bytes) - { - *((long*)b) = _field1; - *((long*)(b + 8)) = _field2; - } - - return new IPEndPoint(new IPAddress(bytes, ScopeId), port); - } - } - - public uint ScopeId - { - [MethodImpl(InlineMethod.AggressiveInlining)] - get => (uint)_field3; - set - { - _field3 &= unchecked((long)0xFFFFFFFF00000000); - _field3 |= value; - } - } - - [MethodImpl(InlineMethod.AggressiveInlining)] - private bool IsIPv4MappedToIPv6() - { - // If the IPAddress is an IPv4 mapped to IPv6, return the IPv4 representation instead. - // For example [::FFFF:127.0.0.1] will be transform to IPAddress of 127.0.0.1 - if (_field1 != 0) { return false; } + #endregion - return (_field2 & 0xFFFFFFFF) == 0xFFFF0000; - } - } + #region Native Callbacks [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void uv_alloc_cb(IntPtr handle, IntPtr suggested_size, out uv_buf_t buf); + internal delegate void uv_close_cb(IntPtr conn); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void uv_read_cb(IntPtr handle, IntPtr nread, ref uv_buf_t buf); + internal delegate void uv_work_cb(IntPtr watcher); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void uv_walk_cb(IntPtr handle, IntPtr arg); + internal delegate void uv_watcher_cb(IntPtr watcher, int status); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void uv_close_cb(IntPtr conn); + internal delegate void uv_poll_cb(IntPtr handle, int status, int events); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void uv_watcher_cb(IntPtr watcher, int status); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void uv_work_cb(IntPtr watcher); + #endregion Native Callbacks - static unsafe class NativeMethods + internal static partial class NativeMethods { - const string LibraryName = "libuv"; + private const string LibraryName = "libuv"; internal const int EOF = (int)uv_err_code.UV_EOF; - internal static void GetSocketAddress(IPEndPoint endPoint, out sockaddr addr) - { - Debug.Assert(endPoint is object); - - string ip = endPoint.Address.ToString(); - var result = endPoint.AddressFamily switch - { - AddressFamily.InterNetwork => uv_ip4_addr(ip, endPoint.Port, out addr), - AddressFamily.InterNetworkV6 => uv_ip6_addr(ip, endPoint.Port, out addr), - _ => throw ThrowHelper.GetNotSupportedException(endPoint), - }; - ThrowIfError(result); - } - - internal static IPEndPoint TcpGetSocketName(IntPtr handle) - { - Debug.Assert(handle != IntPtr.Zero); - - int namelen = Marshal.SizeOf(); - _ = uv_tcp_getsockname(handle, out sockaddr sockaddr, ref namelen); - return sockaddr.GetIPEndPoint(); - } - - internal static IPEndPoint TcpGetPeerName(IntPtr handle) - { - Debug.Assert(handle != IntPtr.Zero); - - int namelen = Marshal.SizeOf(); - int result = uv_tcp_getpeername(handle, out sockaddr sockaddr, ref namelen); - ThrowIfError(result); - return sockaddr.GetIPEndPoint(); - } - #if NETCOREAPP || NETSTANDARD + [MethodImpl(InlineMethod.AggressiveOptimization)] internal static IntPtr Allocate(int size) => Marshal.AllocCoTaskMem(size); + [MethodImpl(InlineMethod.AggressiveOptimization)] internal static void FreeMemory(IntPtr ptr) => Marshal.FreeCoTaskMem(ptr); #else + [MethodImpl(InlineMethod.AggressiveOptimization)] internal static IntPtr Allocate(int size) => Marshal.AllocHGlobal(size); + [MethodImpl(InlineMethod.AggressiveOptimization)] internal static void FreeMemory(IntPtr ptr) => Marshal.FreeHGlobal(ptr); #endif - internal static IntPtr Allocate(uv_handle_type handleType) - { - int size = GetSize(handleType); - return Allocate(size); - } + #region Common - internal static int GetSize(uv_handle_type handleType) => uv_handle_size(handleType).ToInt32(); + internal static bool IsHandleActive(IntPtr handle) => + handle != IntPtr.Zero && (uint)uv_is_active(handle) > 0u; - internal static IntPtr Allocate(uv_req_type requestType, int size = 0) + internal static void AddReference(IntPtr handle) { - size += GetSize(requestType); - return Allocate(size); - } - - internal static int GetSize(uv_req_type requestType) => uv_req_size(requestType).ToInt32(); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_listen(IntPtr handle, int backlog, uv_watcher_cb connection_cb); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_accept(IntPtr server, IntPtr client); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_send_buffer_size(IntPtr handle, ref IntPtr value); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_recv_buffer_size(IntPtr handle, ref IntPtr value); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_is_readable(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_is_writable(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_read_start(IntPtr handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_read_stop(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_write(IntPtr req, IntPtr handle, uv_buf_t* bufs, int nbufs, uv_watcher_cb cb); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_write2(IntPtr req, IntPtr handle, uv_buf_t[] bufs, int nbufs, IntPtr sendHandle, uv_watcher_cb cb); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_ip4_addr(string ip, int port, out sockaddr address); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_ip6_addr(string ip, int port, out sockaddr address); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_connect(IntPtr req, IntPtr handle, ref sockaddr sockaddr, uv_watcher_cb connect_cb); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_init(IntPtr loopHandle, IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_init_ex(IntPtr loopHandle, IntPtr handle, uint flags); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_bind(IntPtr handle, ref sockaddr sockaddr, uint flags); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_getsockname(IntPtr handle, out sockaddr sockaddr, ref int namelen); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_getpeername(IntPtr handle, out sockaddr name, ref int namelen); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_nodelay(IntPtr handle, int enable); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_keepalive(IntPtr handle, int enable, int delay); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_tcp_simultaneous_accepts(IntPtr handle, int enable); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr uv_handle_size(uv_handle_type handleType); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_close(IntPtr handle, uv_close_cb close_cb); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_is_closing(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_ref(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_unref(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_has_ref(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_is_active(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_loop_init(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_stop(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_loop_close(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_loop_alive(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_run(IntPtr handle, uv_run_mode mode); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr uv_loop_size(); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_update_time(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern long uv_now(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern long uv_hrtime(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_backend_timeout(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_walk(IntPtr handle, uv_walk_cb walk_cb, IntPtr arg); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_async_init(IntPtr loopHandle, IntPtr handle, uv_work_cb async_cb); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_async_send(IntPtr handle); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr uv_req_size(uv_req_type reqType); - - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_pipe_init(IntPtr loop, IntPtr handle, int ipc); + Debug.Assert(handle != IntPtr.Zero); - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_pipe_bind(IntPtr handle, string name); + uv_ref(handle); + } - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_pipe_connect(IntPtr req, IntPtr handle, string name, uv_watcher_cb connect_cb); + internal static void ReleaseReference(IntPtr handle) + { + Debug.Assert(handle != IntPtr.Zero); - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_pipe_getsockname(IntPtr handle, IntPtr buffer, ref IntPtr size); + uv_unref(handle); + } - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_pipe_getpeername(IntPtr handle, IntPtr buffer, ref IntPtr size); + internal static bool HadReference(IntPtr handle) => + handle != IntPtr.Zero && (uint)uv_has_ref(handle) > 0u; - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_pipe_pending_instances(IntPtr handle, int count); + internal static void CloseHandle(IntPtr handle, uv_close_cb callback) + { + if (handle == IntPtr.Zero || callback is null) + { + return; + } - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_pipe_pending_count(IntPtr handle); + int result = uv_is_closing(handle); + if (0u >= (uint)result) + { + uv_close(handle, callback); + } + } - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_pipe_pending_type(IntPtr handle); + internal static bool IsHandleClosing(IntPtr handle) => + handle != IntPtr.Zero && (uint)uv_is_closing(handle) > 0u; [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_shutdown(IntPtr requestHandle, IntPtr streamHandle, uv_watcher_cb callback); + private static extern void uv_close(IntPtr handle, uv_close_cb close_cb); [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_fileno(IntPtr handle, ref IntPtr socket); + private static extern int uv_is_closing(IntPtr handle); [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_timer_init(IntPtr loopHandle, IntPtr handle); + private static extern void uv_ref(IntPtr handle); [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_timer_start(IntPtr handle, uv_work_cb work_cb, long timeout, long repeat); + private static extern void uv_unref(IntPtr handle); [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_timer_stop(IntPtr handle); + private static extern int uv_has_ref(IntPtr handle); [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern int uv_timer_again(IntPtr handle); + private static extern int uv_is_active(IntPtr handle); - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern void uv_timer_set_repeat(IntPtr handle, long repeat); + #endregion Common - [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static extern long uv_timer_get_repeat(IntPtr handle); + #region Error - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InlineMethod.AggressiveOptimization)] internal static void ThrowIfError(int code) { - if (code < 0) + if ((uint)code > SharedConstants.TooBigOrNegative) // < 0 { ThrowOperationException((uv_err_code)code); } @@ -583,25 +213,51 @@ internal static void ThrowIfError(int code) [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowOperationException(uv_err_code error) => throw CreateError(error); - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowObjectDisposedException(string message) => throw new ObjectDisposedException(message); - internal static OperationException CreateError(uv_err_code error) { - IntPtr ptr = uv_err_name(error); - string name = ptr != IntPtr.Zero ? Marshal.PtrToStringAnsi(ptr) : null; + string name = GetErrorName(error); + string description = GetErrorDescription(error); + return new OperationException((int)error, name, description); + } - ptr = uv_strerror(error); - string description = ptr != IntPtr.Zero ? Marshal.PtrToStringAnsi(ptr) : null; + private static string GetErrorDescription(uv_err_code code) + { + IntPtr ptr = uv_strerror(code); + if (ptr == IntPtr.Zero) { return null; } + return Marshal.PtrToStringAnsi(ptr); + } - return new OperationException((int)error, name, description); + private static string GetErrorName(uv_err_code code) + { + IntPtr ptr = uv_err_name(code); + if (ptr == IntPtr.Zero) { return null; } + return Marshal.PtrToStringAnsi(ptr); } [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - static extern IntPtr uv_strerror(uv_err_code err); + private static extern IntPtr uv_strerror(uv_err_code err); [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] - static extern IntPtr uv_err_name(uv_err_code err); -#pragma warning restore IDE1006 // 命名样式 + private static extern IntPtr uv_err_name(uv_err_code err); + + #endregion Error + + #region Version + + internal static Version GetVersion() + { + uint version = uv_version(); + int major = (int)(version & 0xFF0000) >> 16; + int minor = (int)(version & 0xFF00) >> 8; + int patch = (int)(version & 0xFF); + + return new Version(major, minor, patch); + } + + [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)] + private static extern uint uv_version(); + + #endregion Version } +#pragma warning restore IDE1006 // 命名样式 } diff --git a/src/DotNetty.Transport.Libuv/Native/NativeRequest.cs b/src/DotNetty.Transport.Libuv/Native/NativeRequest.cs deleted file mode 100644 index d3f0e42f6..000000000 --- a/src/DotNetty.Transport.Libuv/Native/NativeRequest.cs +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using DotNetty.Common.Internal.Logging; - using System; - using System.Diagnostics; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - - abstract unsafe class NativeRequest : IDisposable - { - protected static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); - - readonly uv_req_type _requestType; - protected internal IntPtr Handle; - - protected NativeRequest(uv_req_type requestType, int size) - { - IntPtr handle = NativeMethods.Allocate(requestType, size); - - GCHandle gcHandle = GCHandle.Alloc(this, GCHandleType.Normal); - *(IntPtr*)handle = GCHandle.ToIntPtr(gcHandle); - - Handle = handle; - _requestType = requestType; - } - - protected bool IsValid - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Handle != IntPtr.Zero; - } - - protected void CloseHandle() - { - IntPtr handle = Handle; - if (handle == IntPtr.Zero) - { - return; - } - - IntPtr pHandle = ((uv_req_t*)handle)->data; - - // Free GCHandle - if (pHandle != IntPtr.Zero) - { - GCHandle nativeHandle = GCHandle.FromIntPtr(pHandle); - if (nativeHandle.IsAllocated) - { - nativeHandle.Free(); - ((uv_req_t*)handle)->data = IntPtr.Zero; - } - } - - // Release memory - NativeMethods.FreeMemory(handle); - Handle = IntPtr.Zero; - } - - protected virtual void Dispose(bool disposing) - { - try - { - if (IsValid) - { - CloseHandle(); - } - } - catch (Exception exception) - { - Logger.ErrorWhilstClosingHandle(_requestType ,Handle, exception); - - // For finalizer, we cannot allow this to escape. - if (disposing) throw; - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - ~NativeRequest() => Dispose(false); - - internal static T GetTarget(IntPtr handle) - { - Debug.Assert(handle != IntPtr.Zero); - - IntPtr internalHandle = ((uv_req_t*)handle)->data; - if (internalHandle != IntPtr.Zero) - { - GCHandle gcHandle = GCHandle.FromIntPtr(internalHandle); - if (gcHandle.IsAllocated) - { - return (T)gcHandle.Target; - } - } - return default; - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/OperationException.cs b/src/DotNetty.Transport.Libuv/Native/OperationException.cs index bf993e98d..8572b806a 100644 --- a/src/DotNetty.Transport.Libuv/Native/OperationException.cs +++ b/src/DotNetty.Transport.Libuv/Native/OperationException.cs @@ -1,25 +1,11 @@ /* - * Copyright 2012 The Netty Project + * Copyright (c) Johnny Z. All rights reserved. * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty + * https://github.com/StormHub/NetUV * * Licensed under the MIT license. See LICENSE file in the project root for full license information. * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) * * https://github.com/cuteant/dotnetty-span-fork * @@ -33,16 +19,23 @@ namespace DotNetty.Transport.Libuv.Native public sealed class OperationException : Exception { - static readonly CachedReadConcurrentDictionary s_errorCodeCache = new CachedReadConcurrentDictionary(StringComparer.Ordinal); - static readonly Func s_convertErrorCodeFunc = e => ConvertErrorCode(e); + private static readonly CachedReadConcurrentDictionary s_errorCodeCache; + private static readonly Func s_convertErrorCodeFunc; + + static OperationException() + { + s_errorCodeCache = new CachedReadConcurrentDictionary(StringComparer.Ordinal); + s_convertErrorCodeFunc = e => ConvertErrorCode(e); + } public OperationException(int errorCode, string errorName, string description) + : base($"{errorName} : {description}") { - this.Code = errorCode; - this.Name = errorName; - this.Description = description; + Code = errorCode; + Name = errorName; + Description = description; - this.ErrorCode = s_errorCodeCache.GetOrAdd(errorName, s_convertErrorCodeFunc); + ErrorCode = s_errorCodeCache.GetOrAdd(errorName, s_convertErrorCodeFunc); } public int Code { get; } @@ -53,7 +46,7 @@ public OperationException(int errorCode, string errorName, string description) public ErrorCode ErrorCode { get; } - public override string Message => $"{this.Name} ({this.ErrorCode}) : {this.Description}"; + public override string Message => $"{Name} ({ErrorCode}) : {base.Message}"; static ErrorCode ConvertErrorCode(string errorName) { @@ -64,86 +57,4 @@ static ErrorCode ConvertErrorCode(string errorName) return value; } } - -#pragma warning disable IDE1006 // 命名样式 - enum uv_err_code -#pragma warning restore IDE1006 // 命名样式 - { - UV_OK = 0, - UV_E2BIG, - UV_EACCES, - UV_EADDRINUSE, - UV_EADDRNOTAVAIL, - UV_EAFNOSUPPORT, - UV_EAGAIN, - UV_EAI_ADDRFAMILY, - UV_EAI_AGAIN, - UV_EAI_BADFLAGS, - UV_EAI_BADHINTS, - UV_EAI_CANCELED, - UV_EAI_FAIL, - UV_EAI_FAMILY, - UV_EAI_MEMORY, - UV_EAI_NODATA, - UV_EAI_NONAME, - UV_EAI_OVERFLOW, - UV_EAI_PROTOCOL, - UV_EAI_SERVICE, - UV_EAI_SOCKTYPE, - UV_EALREADY, - UV_EBADF, - UV_EBUSY, - UV_ECANCELED, - UV_ECHARSET, - UV_ECONNABORTED, - UV_ECONNREFUSED, - UV_ECONNRESET, - UV_EDESTADDRREQ, - UV_EEXIST, - UV_EFAULT, - UV_EFBIG, - UV_EHOSTUNREACH, - UV_EINTR, - UV_EINVAL, - UV_EIO, - UV_EISCONN, - UV_EISDIR, - UV_ELOOP, - UV_EMFILE, - UV_EMSGSIZE, - UV_ENAMETOOLONG, - UV_ENETDOWN, - UV_ENETUNREACH, - UV_ENFILE, - UV_ENOBUFS, - UV_ENODEV, - UV_ENOENT, - UV_ENOMEM, - UV_ENONET, - UV_ENOPROTOOPT, - UV_ENOSPC, - UV_ENOSYS, - UV_ENOTCONN, - UV_ENOTDIR, - UV_ENOTEMPTY, - UV_ENOTSOCK, - UV_ENOTSUP, - UV_EPERM, - UV_EPIPE, - UV_EPROTO, - UV_EPROTONOSUPPORT, - UV_EPROTOTYPE, - UV_ERANGE, - UV_EROFS, - UV_ESHUTDOWN, - UV_ESPIPE, - UV_ESRCH, - UV_ETIMEDOUT, - UV_ETXTBSY, - UV_EXDEV, - UV_UNKNOWN, - UV_EOF = -4095, - UV_ENXIO, - UV_EMLINK, - } } diff --git a/src/DotNetty.NetUV/Native/PendingRead.cs b/src/DotNetty.Transport.Libuv/Native/PendingRead.cs similarity index 97% rename from src/DotNetty.NetUV/Native/PendingRead.cs rename to src/DotNetty.Transport.Libuv/Native/PendingRead.cs index 0c6207221..405d9846e 100644 --- a/src/DotNetty.NetUV/Native/PendingRead.cs +++ b/src/DotNetty.Transport.Libuv/Native/PendingRead.cs @@ -12,7 +12,7 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Native +namespace DotNetty.Transport.Libuv.Native { using System; using System.Diagnostics; diff --git a/src/DotNetty.Transport.Libuv/Native/Pipe.cs b/src/DotNetty.Transport.Libuv/Native/Pipe.cs deleted file mode 100644 index a961149e8..000000000 --- a/src/DotNetty.Transport.Libuv/Native/Pipe.cs +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Diagnostics; - using System.Runtime.InteropServices; - using DotNetty.Common.Internal; - - /// - /// IPC pipe for recieving handles from different libuv loops - /// - sealed unsafe class Pipe : PipeHandle - { - static readonly uv_alloc_cb AllocateCallback = OnAllocateCallback; - static readonly uv_read_cb ReadCallback = OnReadCallback; - - readonly Scratch _scratch; - - Action _readCallback; - - internal Pipe(Loop loop, bool ipc) : base(loop, ipc) - { - _scratch = new Scratch(); - } - - public void ReadStart(Action readAction) - { - Validate(); - - int result = NativeMethods.uv_read_start(Handle, AllocateCallback, ReadCallback); - NativeMethods.ThrowIfError(result); - _readCallback = readAction; - } - - public void ReadStop() - { - if (Handle == IntPtr.Zero) - { - return; - } - - // This function is idempotent and may be safely called on a stopped stream. - int result = NativeMethods.uv_read_stop(Handle); - NativeMethods.ThrowIfError(result); - } - - void OnReadCallback(int status) => _readCallback(this, status); - - internal Tcp GetPendingHandle() - { - Tcp client = null; - - IntPtr loopHandle = ((uv_stream_t*)Handle)->loop; - var loop = GetTarget(loopHandle); - int count = NativeMethods.uv_pipe_pending_count(Handle); - - if (count > 0) - { - var type = (uv_handle_type)NativeMethods.uv_pipe_pending_type(Handle); - if (type == uv_handle_type.UV_TCP) - { - client = new Tcp(loop); - } - else - { - ThrowHelper.ThrowInvalidOperationException_ExpectingTcpHandle(type); - } - - int result = NativeMethods.uv_accept(Handle, client.Handle); - NativeMethods.ThrowIfError(result); - } - - return client; - } - - internal void Send(NativeHandle serverHandle) - { - Debug.Assert(serverHandle is object); - - var ping = new Ping(serverHandle); - uv_buf_t[] bufs = ping.Bufs; - int result = NativeMethods.uv_write2( - ping.Handle, - Handle, - bufs, - bufs.Length, - serverHandle.Handle, - Ping.WriteCallback); - - if (result < 0) - { - ping.Dispose(); - NativeMethods.ThrowOperationException((uv_err_code)result); - } - } - - protected override void OnClosed() - { - base.OnClosed(); - _scratch.Dispose(); - } - - static void OnReadCallback(IntPtr handle, IntPtr nread, ref uv_buf_t buf) - { - var pipe = GetTarget(handle); - pipe.OnReadCallback((int)nread.ToInt64()); - } - - static void OnAllocateCallback(IntPtr handle, IntPtr suggestedSize, out uv_buf_t buf) - { - var pipe = GetTarget(handle); - pipe.OnAllocateCallback(out buf); - } - - void OnAllocateCallback(out uv_buf_t buf) - { - buf = _scratch.Buf; - } - - sealed class Scratch : IDisposable - { - static readonly byte[] ScratchBuf = new byte[64]; - GCHandle _gcHandle; - - public Scratch() - { - byte[] scratch = ScratchBuf; - _gcHandle = GCHandle.Alloc(scratch, GCHandleType.Pinned); - IntPtr arrayHandle = _gcHandle.AddrOfPinnedObject(); - Buf = new uv_buf_t(arrayHandle, scratch.Length); - } - - internal readonly uv_buf_t Buf; - - public void Dispose() - { - if (_gcHandle.IsAllocated) - { - _gcHandle.Free(); - } - } - } - - sealed class Ping : NativeRequest - { - internal static readonly uv_watcher_cb WriteCallback = (h, s) => OnWriteCallback(h, s); - static readonly byte[] PingBuf = TextEncodings.UTF8NoBOM.GetBytes("PING"); - - readonly NativeHandle _sentHandle; - GCHandle _gcHandle; - - public Ping(NativeHandle sentHandle) : base(uv_req_type.UV_WRITE, 0) - { - _sentHandle = sentHandle; - byte[] array = PingBuf; - Bufs = new uv_buf_t[1]; - - GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); - IntPtr arrayHandle = handle.AddrOfPinnedObject(); - _gcHandle = handle; - - Bufs[0] = new uv_buf_t(arrayHandle, array.Length); - } - - internal readonly uv_buf_t[] Bufs; - - void OnWriteCallback(int status) - { - if (status < 0) - { - OperationException error = NativeMethods.CreateError((uv_err_code)status); - if (Logger.WarnEnabled) Logger.FailedToWriteServerHandleToClient(error); - } - - _sentHandle.CloseHandle(); - Dispose(); - } - - static void OnWriteCallback(IntPtr handle, int status) - { - var request = GetTarget(handle); - request.OnWriteCallback(status); - } - - protected override void Dispose(bool disposing) - { - if (_gcHandle.IsAllocated) - { - _gcHandle.Free(); - } - base.Dispose(disposing); - } - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/PipeHandle.cs b/src/DotNetty.Transport.Libuv/Native/PipeHandle.cs deleted file mode 100644 index 6491f3434..000000000 --- a/src/DotNetty.Transport.Libuv/Native/PipeHandle.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Diagnostics; - using System.Runtime.InteropServices; - - abstract unsafe class PipeHandle : NativeHandle - { - const int NameBufferSize = 512; - - protected PipeHandle(Loop loop, bool ipc) : base(uv_handle_type.UV_NAMED_PIPE) - { - Debug.Assert(loop is object); - - IntPtr handle = NativeMethods.Allocate(uv_handle_type.UV_NAMED_PIPE); - try - { - int result = NativeMethods.uv_pipe_init(loop.Handle, handle, ipc ? 1 : 0); - NativeMethods.ThrowIfError(result); - } - catch - { - NativeMethods.FreeMemory(handle); - throw; - } - - GCHandle gcHandle = GCHandle.Alloc(this, GCHandleType.Normal); - ((uv_handle_t*)handle)->data = GCHandle.ToIntPtr(gcHandle); - Handle = handle; - } - - public void Bind(string name) - { - Debug.Assert(!string.IsNullOrEmpty(name)); - - Validate(); - int result = NativeMethods.uv_pipe_bind(Handle, name); - NativeMethods.ThrowIfError(result); - } - - public string GetSocketName() - { - Validate(); - var buf = stackalloc byte[NameBufferSize]; - var length = (IntPtr)NameBufferSize; - var ptr = (IntPtr)buf; - - int result = NativeMethods.uv_pipe_getsockname(Handle, ptr, ref length); - NativeMethods.ThrowIfError(result); - - string socketName = Marshal.PtrToStringAnsi(ptr, length.ToInt32()); - return socketName; - } - - public string GetPeerName() - { - Validate(); - - var buf = stackalloc byte[NameBufferSize]; - var length = (IntPtr)NameBufferSize; - var ptr = (IntPtr)buf; - - int result = NativeMethods.uv_pipe_getpeername(Handle, ptr, ref length); - NativeMethods.ThrowIfError(result); - - string peerName = Marshal.PtrToStringAnsi(ptr, length.ToInt32()); - return peerName; - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/PipeListener.cs b/src/DotNetty.Transport.Libuv/Native/PipeListener.cs deleted file mode 100644 index 0f2844c09..000000000 --- a/src/DotNetty.Transport.Libuv/Native/PipeListener.cs +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Threading; - - /// - /// IPC pipe server to hand out handles to different libuv loops. - /// - sealed class PipeListener : PipeHandle - { - private const int DefaultPipeBacklog = 128; - private static readonly uv_watcher_cb ConnectionCallback = (h, s) => OnConnectionCallback(h, s); - - private readonly Action _onReadAction; - private readonly List _pipes; - private readonly WindowsApi _windowsApi; - private int _requestId; - - public PipeListener(Loop loop, bool ipc) : base(loop, ipc) - { - _onReadAction = (p, s) => OnRead(p, s); - - _pipes = new List(); - _windowsApi = new WindowsApi(); - _requestId = 0; - } - - public void Listen(string name, int backlog = DefaultPipeBacklog) - { - Debug.Assert(backlog > 0); - - Validate(); - int result = NativeMethods.uv_pipe_bind(Handle, name); - NativeMethods.ThrowIfError(result); - - result = NativeMethods.uv_listen(Handle, backlog, ConnectionCallback); - NativeMethods.ThrowIfError(result); - } - - internal void Shutdown() - { - Pipe[] handles = _pipes.ToArray(); - _pipes.Clear(); - - foreach (Pipe pipe in handles) - { - pipe.CloseHandle(); - } - - CloseHandle(); - } - - internal void DispatchHandle(NativeHandle handle) - { - if (0u >= (uint)_pipes.Count) - { - ThrowHelper.ThrowInvalidOperationException_Dispatch(); - } - - int id = Interlocked.Increment(ref _requestId); - Pipe pipe = _pipes[Math.Abs(id % _pipes.Count)]; - - _windowsApi.DetachFromIOCP(handle); - pipe.Send(handle); - } - - private unsafe void OnConnectionCallback(int status) - { - Pipe client = null; - try - { - if (status < 0) - { - throw NativeMethods.CreateError((uv_err_code)status); - } - else - { - IntPtr loopHandle = ((uv_stream_t*)Handle)->loop; - var loop = GetTarget(loopHandle); - - client = new Pipe(loop, true); // IPC pipe - int result = NativeMethods.uv_accept(Handle, client.Handle); - NativeMethods.ThrowIfError(result); - - _pipes.Add(client); - client.ReadStart(_onReadAction); - } - } - catch (Exception exception) - { - client?.CloseHandle(); - if (Logger.WarnEnabled) Logger.FailedToSendServerHandleToClient(exception); - } - } - - private void OnRead(Pipe pipe, int status) - { - // The server connection is never meant to read anything back - // it is only used for passing handles over to different loops - // Therefore the only message should come back is EOF - if (status >= 0) - { - return; - } - - _windowsApi.Dispose(); - _ = _pipes.Remove(pipe); - pipe.CloseHandle(); - - if (status != NativeMethods.EOF) - { - OperationException error = NativeMethods.CreateError((uv_err_code)status); - if (Logger.WarnEnabled) Logger.ReadError(error); - } - } - - private static void OnConnectionCallback(IntPtr handle, int status) - { - var server = GetTarget(handle); - server.OnConnectionCallback(status); - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/PlatformApi.cs b/src/DotNetty.Transport.Libuv/Native/PlatformApi.cs deleted file mode 100644 index 01dcce2d2..000000000 --- a/src/DotNetty.Transport.Libuv/Native/PlatformApi.cs +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Net.Sockets; - using System.Runtime.InteropServices; - - static partial class PlatformApi - { - const int AF_INET6_LINUX = 10; - const int AF_INET6_OSX = 30; - - internal static uint GetAddressFamily(AddressFamily addressFamily) - { - // AF_INET 2 - if (addressFamily == AddressFamily.InterNetwork || IsWindows) - { - return (uint)addressFamily; - } - - if (IsLinux) - { - return AF_INET6_LINUX; - } - - if (IsDarwin) - { - return AF_INET6_OSX; - } - - return ThrowHelper.ThrowInvalidOperationException_Dispatch(addressFamily); - } - - internal static bool GetReuseAddress(TcpHandle tcpHandle) - { - IntPtr socketHandle = GetSocketHandle(tcpHandle); - - return IsWindows - ? WindowsApi.GetReuseAddress(socketHandle) - : UnixApi.GetReuseAddress(socketHandle); - } - - internal static void SetReuseAddress(TcpHandle tcpHandle, int value) - { - IntPtr socketHandle = GetSocketHandle(tcpHandle); - if (IsWindows) - { - WindowsApi.SetReuseAddress(socketHandle, value); - } - else - { - UnixApi.SetReuseAddress(socketHandle, value); - } - } - - internal static bool GetReusePort(TcpHandle tcpHandle) - { - if (IsWindows) - { - return GetReuseAddress(tcpHandle); - } - - IntPtr socketHandle = GetSocketHandle(tcpHandle); - return UnixApi.GetReusePort(socketHandle); - } - - internal static void SetReusePort(TcpHandle tcpHandle, int value) - { - IntPtr socketHandle = GetSocketHandle(tcpHandle); - // Ignore SO_REUSEPORT on Windows because it is controlled - // by SO_REUSEADDR - if (IsWindows) - { - return; - } - - UnixApi.SetReusePort(socketHandle, value); - } - - static IntPtr GetSocketHandle(TcpHandle handle) - { - IntPtr socket = IntPtr.Zero; - _ = NativeMethods.uv_fileno(handle.Handle, ref socket); - return socket; - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/PlatformApis.cs b/src/DotNetty.Transport.Libuv/Native/PlatformApis.cs new file mode 100644 index 000000000..e9e362e6d --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Native/PlatformApis.cs @@ -0,0 +1,143 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. + * + * https://github.com/azure/dotnetty + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. + * + * https://github.com/cuteant/dotnetty-span-fork + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +namespace DotNetty.Transport.Libuv.Native +{ + using System; + using System.Net.Sockets; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + + static class PlatformApis + { + const int AF_INET6_LINUX = 10; + const int AF_INET6_OSX = 30; + +#if NETCOREAPP || NETSTANDARD + [MethodImpl(InlineMethod.AggressiveOptimization)] + internal static IntPtr Allocate(int size) => Marshal.AllocCoTaskMem(size); + + [MethodImpl(InlineMethod.AggressiveOptimization)] + internal static void FreeMemory(IntPtr ptr) => Marshal.FreeCoTaskMem(ptr); +#else + [MethodImpl(InlineMethod.AggressiveOptimization)] + internal static IntPtr Allocate(int size) => Marshal.AllocHGlobal(size); + + [MethodImpl(InlineMethod.AggressiveOptimization)] + internal static void FreeMemory(IntPtr ptr) => Marshal.FreeHGlobal(ptr); +#endif + internal static string GetPipeName() + { + return GetPipeName("SpanNetty_" + Guid.NewGuid().ToString("n")); + } + + internal static string GetPipeName(string pipeName) + { + if (string.IsNullOrEmpty(pipeName)) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.pipeName); } + + if (Platform.IsWindows) + { + return @"\\.\pipe\" + pipeName; + } + + return "/tmp/" + pipeName; + } + + internal static uint GetAddressFamily(AddressFamily addressFamily) + { + // AF_INET 2 + if (addressFamily == AddressFamily.InterNetwork || Platform.IsWindows) + { + return (uint)addressFamily; + } + + if (Platform.IsLinux) + { + return AF_INET6_LINUX; + } + + if (Platform.IsDarwin) + { + return AF_INET6_OSX; + } + + return ThrowHelper.FromInvalidOperationException_Dispatch(addressFamily); + } + + internal static bool GetReuseAddress(IStreamHandle handle) + { + IntPtr socketHandle = GetSocketHandle(handle); + + if (Platform.IsWindows) + { + return WindowsApi.GetReuseAddress(socketHandle); + } + return UnixApi.GetReuseAddress(socketHandle); + } + + internal static void SetReuseAddress(IStreamHandle handle, int value) + { + IntPtr socketHandle = GetSocketHandle(handle); + if (Platform.IsWindows) + { + WindowsApi.SetReuseAddress(socketHandle, value); + } + else + { + UnixApi.SetReuseAddress(socketHandle, value); + } + } + + internal static bool GetReusePort(IStreamHandle handle) + { + if (Platform.IsWindows) { return GetReuseAddress(handle); } + + IntPtr socketHandle = GetSocketHandle(handle); + return UnixApi.GetReusePort(socketHandle); + } + + internal static void SetReusePort(IStreamHandle handle, int value) + { + IntPtr socketHandle = GetSocketHandle(handle); + // Ignore SO_REUSEPORT on Windows because it is controlled + // by SO_REUSEADDR + if (Platform.IsWindows) { return; } + + UnixApi.SetReusePort(socketHandle, value); + } + + static IntPtr GetSocketHandle(IStreamHandle handle) + { + IntPtr socket = IntPtr.Zero; + handle.GetFileDescriptor(ref socket); + return socket; + } + } +} diff --git a/src/DotNetty.Transport.Libuv/Native/RemoteConnection.cs b/src/DotNetty.Transport.Libuv/Native/RemoteConnection.cs index fa0c234d6..5d89bea2a 100644 --- a/src/DotNetty.Transport.Libuv/Native/RemoteConnection.cs +++ b/src/DotNetty.Transport.Libuv/Native/RemoteConnection.cs @@ -29,16 +29,17 @@ namespace DotNetty.Transport.Libuv.Native { using System; + using DotNetty.Transport.Libuv.Handles; sealed class RemoteConnection { - public RemoteConnection(NativeHandle client, Exception error) + public RemoteConnection(Tcp client, Exception error) { Client = client; Error = error; } - internal NativeHandle Client { get; } + internal Tcp Client { get; } internal Exception Error { get; } } diff --git a/src/DotNetty.Transport.Libuv/Native/Tcp.cs b/src/DotNetty.Transport.Libuv/Native/Tcp.cs deleted file mode 100644 index f9d112436..000000000 --- a/src/DotNetty.Transport.Libuv/Native/Tcp.cs +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Diagnostics; - using System.Net; - - public sealed class Tcp : TcpHandle - { - static readonly uv_alloc_cb AllocateCallback = OnAllocateCallback; - static readonly uv_read_cb ReadCallback = OnReadCallback; - - readonly ReadOperation _pendingRead; - INativeUnsafe _nativeUnsafe; - - internal Tcp(Loop loop, uint flags = 0 /* AF_UNSPEC */ ) : base(loop, flags) - { - _pendingRead = new ReadOperation(); - } - - internal void ReadStart(INativeUnsafe channel) - { - Debug.Assert(channel is object); - - Validate(); - int result = NativeMethods.uv_read_start(Handle, AllocateCallback, ReadCallback); - NativeMethods.ThrowIfError(result); - _nativeUnsafe = channel; - } - - public void ReadStop() - { - if (Handle == IntPtr.Zero) - { - return; - } - - // This function is idempotent and may be safely called on a stopped stream. - _ = NativeMethods.uv_read_stop(Handle); - } - - void OnReadCallback(int statusCode, OperationException error) - { - try - { - _pendingRead.Complete(statusCode, error); - _nativeUnsafe.FinishRead(_pendingRead); - } - catch (Exception exception) - { - if (Logger.WarnEnabled) Logger.TcpHandleReadCallbcakError(Handle, exception); - } - finally - { - _pendingRead.Reset(); - } - } - - static void OnReadCallback(IntPtr handle, IntPtr nread, ref uv_buf_t buf) - { - var tcp = GetTarget(handle); - int status = (int)nread.ToInt64(); - - OperationException error = null; - if (status < 0 && status != NativeMethods.EOF) - { - error = NativeMethods.CreateError((uv_err_code)status); - } - - tcp.OnReadCallback(status, error); - } - - protected override void OnClosed() - { - base.OnClosed(); - - _pendingRead.Dispose(); - _nativeUnsafe = null; - } - - void OnAllocateCallback(out uv_buf_t buf) - { - buf = _nativeUnsafe.PrepareRead(_pendingRead); - } - - static void OnAllocateCallback(IntPtr handle, IntPtr suggestedSize, out uv_buf_t buf) - { - var tcp = GetTarget(handle); - tcp.OnAllocateCallback(out buf); - } - - public IPEndPoint GetPeerEndPoint() - { - Validate(); - return NativeMethods.TcpGetPeerName(Handle); - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/TcpConnect.cs b/src/DotNetty.Transport.Libuv/Native/TcpConnect.cs deleted file mode 100644 index 7c787a75e..000000000 --- a/src/DotNetty.Transport.Libuv/Native/TcpConnect.cs +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System.Diagnostics; - using System.Net; - - sealed class TcpConnect : ConnectRequest - { - readonly INativeUnsafe _nativeUnsafe; - - public TcpConnect(INativeUnsafe nativeUnsafe, IPEndPoint remoteEndPoint) - { - Debug.Assert(nativeUnsafe is object); - Debug.Assert(remoteEndPoint is object); - - NativeMethods.GetSocketAddress(remoteEndPoint, out sockaddr addr); - int result = NativeMethods.uv_tcp_connect( - Handle, - nativeUnsafe.UnsafeHandle, - ref addr, - WatcherCallback); - NativeMethods.ThrowIfError(result); - - _nativeUnsafe = nativeUnsafe; - } - - protected override void OnWatcherCallback() => _nativeUnsafe.FinishConnect(this); - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/TcpHandle.cs b/src/DotNetty.Transport.Libuv/Native/TcpHandle.cs deleted file mode 100644 index dcfda9ae2..000000000 --- a/src/DotNetty.Transport.Libuv/Native/TcpHandle.cs +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Diagnostics; - using System.Net; - using System.Runtime.InteropServices; - - public abstract unsafe class TcpHandle : NativeHandle - { - internal TcpHandle(Loop loop, uint flags) : base(uv_handle_type.UV_TCP) - { - Debug.Assert(loop is object); - - IntPtr handle = NativeMethods.Allocate(uv_handle_type.UV_TCP); - - try - { - // if flags is specified as AF_INET or AF_INET6, Libuv - // creates the socket when tcp handle is created. - // Otherwise the socket is created when bind to an address. - // - // This is for TcpListener to create socket early before bind - int result = 0u >= flags - ? NativeMethods.uv_tcp_init(loop.Handle, handle) - : NativeMethods.uv_tcp_init_ex(loop.Handle, handle, flags); - NativeMethods.ThrowIfError(result); - } - catch - { - NativeMethods.FreeMemory(handle); - throw; - } - - GCHandle gcHandle = GCHandle.Alloc(this, GCHandleType.Normal); - ((uv_handle_t*)handle)->data = GCHandle.ToIntPtr(gcHandle); - Handle = handle; - } - - internal void Bind(IPEndPoint endPoint, bool dualStack = false) - { - Debug.Assert(endPoint is object); - - Validate(); - NativeMethods.GetSocketAddress(endPoint, out sockaddr addr); - int result = NativeMethods.uv_tcp_bind(Handle, ref addr, (uint)(dualStack ? 1 : 0)); - NativeMethods.ThrowIfError(result); - } - - public IPEndPoint GetLocalEndPoint() - { - Validate(); - return NativeMethods.TcpGetSocketName(Handle); - } - - public void NoDelay(int value) - { - Validate(); - int result = NativeMethods.uv_tcp_nodelay(Handle, value); - NativeMethods.ThrowIfError(result); - } - - public int SendBufferSize(int value) - { - if ((uint)value > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_PositiveOrZero(value, ExceptionArgument.value); } - - Validate(); - var size = (IntPtr)value; - int result = NativeMethods.uv_send_buffer_size(Handle, ref size); - NativeMethods.ThrowIfError(result); - - return size.ToInt32(); - } - - public int ReceiveBufferSize(int value) - { - if ((uint)value > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_PositiveOrZero(value, ExceptionArgument.value); } - - Validate(); - var size = (IntPtr)value; - - int result = NativeMethods.uv_recv_buffer_size(Handle, ref size); - NativeMethods.ThrowIfError(result); - - return size.ToInt32(); - } - - public void KeepAlive(int value, int delay) - { - Validate(); - int result = NativeMethods.uv_tcp_keepalive(Handle, value, delay); - NativeMethods.ThrowIfError(result); - } - - public void SimultaneousAccepts(bool value) - { - Validate(); - int result = NativeMethods.uv_tcp_simultaneous_accepts(Handle, value ? 1 : 0); - NativeMethods.ThrowIfError(result); - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/TcpListener.cs b/src/DotNetty.Transport.Libuv/Native/TcpListener.cs deleted file mode 100644 index 973e9896d..000000000 --- a/src/DotNetty.Transport.Libuv/Native/TcpListener.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Diagnostics; - - sealed class TcpListener : TcpHandle - { - static readonly uv_watcher_cb ConnectionCallback = (h, s) => OnConnectionCallback(h, s); - - IServerNativeUnsafe _nativeUnsafe; - - public TcpListener(Loop loop, uint flags) : base(loop, flags) - { - } - - public void Listen(IServerNativeUnsafe channel, int backlog) - { - Debug.Assert(channel is object && _nativeUnsafe is null); - Debug.Assert(backlog > 0); - - int result = NativeMethods.uv_listen(Handle, backlog, ConnectionCallback); - NativeMethods.ThrowIfError(result); - - _nativeUnsafe = channel; - } - - unsafe void OnConnectionCallback(int status) - { - NativeHandle client = null; - Exception error = null; - try - { - if (status < 0) - { - error = NativeMethods.CreateError((uv_err_code)status); - } - else - { - IntPtr loopHandle = ((uv_stream_t*)Handle)->loop; - var loop = GetTarget(loopHandle); - - client = new Tcp(loop); - int result = NativeMethods.uv_accept(Handle, client.Handle); - if (result < 0) - { - error = NativeMethods.CreateError((uv_err_code)result); - } - } - } - catch (Exception exception) - { - error = exception; - } - - _nativeUnsafe.Accept(new RemoteConnection(client, error)); - } - - static void OnConnectionCallback(IntPtr handle, int status) - { - var server = GetTarget(handle); - server.OnConnectionCallback(status); - } - - protected override void OnClosed() - { - _nativeUnsafe = null; - base.OnClosed(); - } - } -} \ No newline at end of file diff --git a/src/DotNetty.Transport.Libuv/Native/Timer.cs b/src/DotNetty.Transport.Libuv/Native/Timer.cs deleted file mode 100644 index 7904a29b7..000000000 --- a/src/DotNetty.Transport.Libuv/Native/Timer.cs +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Diagnostics; - using System.Runtime.InteropServices; - - sealed class Timer : NativeHandle - { - static readonly uv_work_cb WorkCallback = h => OnWorkCallback(h); - - readonly Action _callback; - readonly object _state; - - public unsafe Timer(Loop loop, Action callback, object state) - : base(uv_handle_type.UV_TIMER) - { - Debug.Assert(loop is object); - Debug.Assert(callback is object); - - IntPtr handle = NativeMethods.Allocate(uv_handle_type.UV_TIMER); - - try - { - int result = NativeMethods.uv_timer_init(loop.Handle, handle); - NativeMethods.ThrowIfError(result); - } - catch - { - NativeMethods.FreeMemory(handle); - throw; - } - - GCHandle gcHandle = GCHandle.Alloc(this, GCHandleType.Normal); - ((uv_handle_t*)handle)->data = GCHandle.ToIntPtr(gcHandle); - - Handle = handle; - _callback = callback; - _state = state; - } - - public Timer Start(long timeout, long repeat) - { - Debug.Assert(timeout >= 0); - Debug.Assert(repeat >= 0); - - Validate(); - int result = NativeMethods.uv_timer_start(Handle, WorkCallback, timeout, repeat); - NativeMethods.ThrowIfError(result); - - return this; - } - - public Timer SetRepeat(long repeat) - { - Debug.Assert(repeat >= 0); - - Validate(); - NativeMethods.uv_timer_set_repeat(Handle, repeat); - return this; - } - - public long GetRepeat() - { - Validate(); - return NativeMethods.uv_timer_get_repeat(Handle); - } - - public Timer Again() - { - Validate(); - int result = NativeMethods.uv_timer_again(Handle); - NativeMethods.ThrowIfError(result); - return this; - } - - public void Stop() - { - if (!IsValid) - { - return; - } - - int result = NativeMethods.uv_timer_stop(Handle); - NativeMethods.ThrowIfError(result); - } - - void OnWorkCallback() - { - try - { - _callback(_state); - } - catch (Exception exception) - { - Logger.CallbackRrror(HandleType, Handle, exception); - } - } - - static void OnWorkCallback(IntPtr handle) - { - var workHandle = GetTarget(handle); - workHandle?.OnWorkCallback(); - } - } -} diff --git a/src/DotNetty.Transport.Libuv/Native/UnixApi.cs b/src/DotNetty.Transport.Libuv/Native/UnixApi.cs index 61afac0b2..c6e395ff2 100644 --- a/src/DotNetty.Transport.Libuv/Native/UnixApi.cs +++ b/src/DotNetty.Transport.Libuv/Native/UnixApi.cs @@ -29,8 +29,8 @@ namespace DotNetty.Transport.Libuv.Native { using System; - using System.Net.Sockets; using System.Runtime.InteropServices; + using DotNetty.Common; static class UnixApi { @@ -55,11 +55,11 @@ internal static unsafe bool GetReuseAddress(IntPtr socket) int value = 0; int status = 0; int optLen = sizeof(int); - if (PlatformApi.IsLinux) + if (Platform.IsLinux) { status = getsockopt(socket.ToInt32(), SOL_SOCKET_LINUX, SO_REUSEADDR_LINUX, (byte*)&value, &optLen); } - else if (PlatformApi.IsDarwin) + else if (Platform.IsDarwin) { status = getsockopt(socket.ToInt32(), SOL_SOCKET_OSX, SO_REUSEADDR_OSX, (byte*)&value, &optLen); } @@ -74,11 +74,11 @@ internal static unsafe bool GetReuseAddress(IntPtr socket) internal static unsafe void SetReuseAddress(IntPtr socket, int value) { int status = 0; - if (PlatformApi.IsLinux) + if (Platform.IsLinux) { status = setsockopt(socket.ToInt32(), SOL_SOCKET_LINUX, SO_REUSEADDR_LINUX, (IntPtr)(&value), sizeof(int)); } - else if (PlatformApi.IsDarwin) + else if (Platform.IsDarwin) { status = setsockopt(socket.ToInt32(), SOL_SOCKET_OSX, SO_REUSEADDR_OSX, (IntPtr)(&value), sizeof(int)); } @@ -93,11 +93,11 @@ internal static unsafe bool GetReusePort(IntPtr socket) int value = 0; int status = 0; int optLen = sizeof(int); - if (PlatformApi.IsLinux) + if (Platform.IsLinux) { status = getsockopt(socket.ToInt32(), SOL_SOCKET_LINUX, SO_REUSEPORT_LINUX, (byte*)&value, &optLen); } - else if (PlatformApi.IsDarwin) + else if (Platform.IsDarwin) { status = getsockopt(socket.ToInt32(), SOL_SOCKET_OSX, SO_REUSEPORT_OSX, (byte*)&value, &optLen); } @@ -111,11 +111,11 @@ internal static unsafe bool GetReusePort(IntPtr socket) internal static unsafe void SetReusePort(IntPtr socket, int value) { int status = 0; - if (PlatformApi.IsLinux) + if (Platform.IsLinux) { status = setsockopt(socket.ToInt32(), SOL_SOCKET_LINUX, SO_REUSEPORT_LINUX, (IntPtr)(&value), sizeof(int)); } - else if (PlatformApi.IsDarwin) + else if (Platform.IsDarwin) { status = setsockopt(socket.ToInt32(), SOL_SOCKET_OSX, SO_REUSEPORT_OSX, (IntPtr)(&value), sizeof(int)); } diff --git a/src/DotNetty.Transport.Libuv/Native/WindowsApi.cs b/src/DotNetty.Transport.Libuv/Native/WindowsApi.cs index b48360ab7..731598d0f 100644 --- a/src/DotNetty.Transport.Libuv/Native/WindowsApi.cs +++ b/src/DotNetty.Transport.Libuv/Native/WindowsApi.cs @@ -26,30 +26,30 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -#pragma warning disable 414 -#pragma warning disable 169 namespace DotNetty.Transport.Libuv.Native { using System; using System.Net.Sockets; using System.Runtime.InteropServices; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; //https://github.com/aspnet/KestrelHttpServer/blob/dev/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs sealed class WindowsApi : IDisposable { - IntPtr fileCompletionInfoPtr; - bool tryDetachFromIOCP = PlatformApi.IsWindows; + private IntPtr _fileCompletionInfoPtr; + private bool _tryDetachFromIOCP = Platform.IsWindows; public WindowsApi() { var fileCompletionInfo = new FILE_COMPLETION_INFORMATION { Key = IntPtr.Zero, Port = IntPtr.Zero }; - this.fileCompletionInfoPtr = NativeMethods.Allocate(Marshal.SizeOf(fileCompletionInfo)); - Marshal.StructureToPtr(fileCompletionInfo, this.fileCompletionInfoPtr, false); + _fileCompletionInfoPtr = PlatformApis.Allocate(Marshal.SizeOf(fileCompletionInfo)); + Marshal.StructureToPtr(fileCompletionInfo, _fileCompletionInfoPtr, false); } - public void DetachFromIOCP(NativeHandle handle) + public void DetachFromIOCP(IStreamHandle handle) { - if (!this.tryDetachFromIOCP) + if (!_tryDetachFromIOCP) { return; } @@ -59,21 +59,17 @@ public void DetachFromIOCP(NativeHandle handle) // https://msdn.microsoft.com/en-us/library/cc704588.aspx const uint STATUS_INVALID_INFO_CLASS = 0xC0000003; -#pragma warning disable IDE0059 // 不需要赋值 var statusBlock = new IO_STATUS_BLOCK(); -#pragma warning restore IDE0059 // 不需要赋值 IntPtr socket = IntPtr.Zero; - _ = NativeMethods.uv_fileno(handle.Handle, ref socket); + handle.GetFileDescriptor(ref socket); uint len = (uint)Marshal.SizeOf(); if (NtSetInformationFile(socket, -#pragma warning disable IDE0059 // 不需要赋值 - out statusBlock, this.fileCompletionInfoPtr, len, -#pragma warning restore IDE0059 // 不需要赋值 + out statusBlock, _fileCompletionInfoPtr, len, FileReplaceCompletionInformation) == STATUS_INVALID_INFO_CLASS) { // Replacing IOCP information is only supported on Windows 8.1 or newer - this.tryDetachFromIOCP = false; + _tryDetachFromIOCP = false; } } @@ -135,12 +131,12 @@ static void SetSocketOption(IntPtr socket, SocketOptionName optionName, int valu public void Dispose() { - IntPtr handle = this.fileCompletionInfoPtr; + IntPtr handle = _fileCompletionInfoPtr; if (handle != IntPtr.Zero) { - NativeMethods.FreeMemory(handle); + PlatformApis.FreeMemory(handle); } - this.fileCompletionInfoPtr = IntPtr.Zero; + _fileCompletionInfoPtr = IntPtr.Zero; } } } diff --git a/src/DotNetty.Transport.Libuv/Native/WriteRequest.cs b/src/DotNetty.Transport.Libuv/Native/WriteRequest.cs deleted file mode 100644 index 66fbba082..000000000 --- a/src/DotNetty.Transport.Libuv/Native/WriteRequest.cs +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) The DotNetty Project (Microsoft). All rights reserved. - * - * https://github.com/azure/dotnetty - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -namespace DotNetty.Transport.Libuv.Native -{ - using System; - using System.Buffers; - using System.Collections.Generic; - using System.Diagnostics; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - using DotNetty.Buffers; - using DotNetty.Common; - using DotNetty.Transport.Channels; - - sealed class WriteRequest : NativeRequest, ChannelOutboundBuffer.IMessageProcessor - { - private static readonly int BufferSize; - private static readonly uv_watcher_cb WriteCallback = (h, s) => OnWriteCallback(h, s); - - private const int MaximumBytes = int.MaxValue; - private const int MaximumLimit = 64; - - static WriteRequest() - { - BufferSize = Marshal.SizeOf(); - } - - private readonly int _maxBytes; - private readonly ThreadLocalPool.Handle _recyclerHandle; - private readonly List _handles; - - private IntPtr _bufs; - private GCHandle _pin; - private int _count; - private int _size; - - private INativeUnsafe _nativeUnsafe; - - public WriteRequest(ThreadLocalPool.Handle recyclerHandle) - : base(uv_req_type.UV_WRITE, BufferSize * MaximumLimit) - { - _recyclerHandle = recyclerHandle; - - int offset = NativeMethods.GetSize(uv_req_type.UV_WRITE); - IntPtr addr = Handle; - - _maxBytes = MaximumBytes; - _bufs = addr + offset; - _pin = GCHandle.Alloc(addr, GCHandleType.Pinned); - _handles = new List(MaximumLimit + 1); - } - - internal void DoWrite(INativeUnsafe channelUnsafe, ChannelOutboundBuffer input) - { - Debug.Assert(_nativeUnsafe is null); - - _nativeUnsafe = channelUnsafe; - input.ForEachFlushedMessage(this); - DoWrite(); - } - - bool Add(IByteBuffer buf) - { - if (_count == MaximumLimit) { return false; } - - int len = buf.ReadableBytes; - if (0u >= (uint)len) { return true; } - - if (_maxBytes - len < _size && _count > 0) { return false; } - - if (buf.IsSingleIoBuffer) - { - var memory = buf.UnreadMemory; - Add(memory.Pin(), memory.Length); - return true; - } - - return AddMany(buf); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - bool AddMany(IByteBuffer buf) - { - if (MaximumLimit - buf.IoBufferCount < _count) { return false; } - - var segments = buf.UnreadSequence; - foreach (var memory in segments) - { - Add(memory.Pin(), memory.Length); - } - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - unsafe void Add(MemoryHandle memoryHandle, int len) - { - _handles.Add(memoryHandle); - IntPtr baseOffset = MemoryAddress(_count); - _size += len; - ++_count; - uv_buf_t.InitMemory(baseOffset, (IntPtr)memoryHandle.Pointer, len); - } - - unsafe void DoWrite() - { - int result = NativeMethods.uv_write( - Handle, - _nativeUnsafe.UnsafeHandle, - (uv_buf_t*)_bufs, - _count, - WriteCallback); - - if (result < 0) - { - Release(); - NativeMethods.ThrowOperationException((uv_err_code)result); - } - } - - public bool ProcessMessage(object msg) => msg is IByteBuffer buf && Add(buf); - - void Release() - { - var handleCount = _handles.Count; - if (handleCount > 0) - { - for (int i = 0; i < handleCount; i++) - { - _handles[i].Dispose(); - } - _handles.Clear(); - } - - _nativeUnsafe = null; - _count = 0; - _size = 0; - _recyclerHandle.Release(this); - } - - void OnWriteCallback(int status) - { - INativeUnsafe @unsafe = _nativeUnsafe; - int bytesWritten = _size; - Release(); - - OperationException error = null; - if (status < 0) - { - error = NativeMethods.CreateError((uv_err_code)status); - } - @unsafe.FinishWrite(bytesWritten, error); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - IntPtr MemoryAddress(int offset) => _bufs + BufferSize * offset; - - static void OnWriteCallback(IntPtr handle, int status) - { - var request = GetTarget(handle); - request.OnWriteCallback(status); - } - - void Free() - { - Release(); - if (_pin.IsAllocated) - { - _pin.Free(); - } - _bufs = IntPtr.Zero; - } - - protected override void Dispose(bool disposing) - { - if (_bufs != IntPtr.Zero) - { - Free(); - } - base.Dispose(disposing); - } - } -} \ No newline at end of file diff --git a/src/DotNetty.Transport.Libuv/NativeChannel.Unsafe.cs b/src/DotNetty.Transport.Libuv/NativeChannel.Unsafe.cs index bafe4cf5f..ef8659b32 100644 --- a/src/DotNetty.Transport.Libuv/NativeChannel.Unsafe.cs +++ b/src/DotNetty.Transport.Libuv/NativeChannel.Unsafe.cs @@ -35,17 +35,17 @@ namespace DotNetty.Transport.Libuv using DotNetty.Buffers; using DotNetty.Common.Utilities; using DotNetty.Transport.Channels; + using DotNetty.Transport.Libuv.Handles; using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Requests; partial class NativeChannel { - public abstract class NativeChannelUnsafe : AbstractUnsafe, INativeUnsafe + public abstract class NativeChannelUnsafe : AbstractUnsafe, INativeChannelUnsafe { private static readonly Action CancelConnectAction = (c, s) => CancelConnect(c, s); - protected NativeChannelUnsafe() : base() - { - } + protected NativeChannelUnsafe() : base() { } public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) { @@ -95,7 +95,7 @@ static void CancelConnect(object context, object state) } // Connect request callback from libuv thread - void INativeUnsafe.FinishConnect(ConnectRequest request) + void INativeChannelUnsafe.FinishConnect(Tcp tcp, OperationException error) { var ch = _channel; _ = (ch._connectCancellationTask?.Cancel()); @@ -106,7 +106,6 @@ void INativeUnsafe.FinishConnect(ConnectRequest request) { if (promise is object) // Not cancelled from timed out { - OperationException error = request.Error; if (error is object) { if (error.ErrorCode == ErrorCode.ETIMEDOUT) @@ -136,7 +135,6 @@ void INativeUnsafe.FinishConnect(ConnectRequest request) } finally { - request.Dispose(); ch._connectPromise = null; if (!success) { @@ -145,10 +143,10 @@ void INativeUnsafe.FinishConnect(ConnectRequest request) } } - public abstract IntPtr UnsafeHandle { get; } + public abstract IScheduleHandle UnsafeHandle { get; } // Allocate callback from libuv thread - uv_buf_t INativeUnsafe.PrepareRead(ReadOperation readOperation) + uv_buf_t INativeChannelUnsafe.PrepareRead(ReadOperation readOperation) { Debug.Assert(readOperation is object); @@ -164,7 +162,7 @@ uv_buf_t INativeUnsafe.PrepareRead(ReadOperation readOperation) } // Read callback from libuv thread - void INativeUnsafe.FinishRead(ReadOperation operation) + void INativeChannelUnsafe.FinishRead(ReadOperation operation) { var ch = _channel; IChannelConfiguration config = ch.Configuration; @@ -255,7 +253,7 @@ protected sealed override void Flush0() } // Write request callback from libuv thread - void INativeUnsafe.FinishWrite(int bytesWritten, OperationException error) + void INativeChannelUnsafe.FinishWrite(int bytesWritten, OperationException error) { var ch = _channel; bool resetWritePending = ch.TryResetState(StateFlags.WriteScheduled); @@ -286,17 +284,4 @@ void INativeUnsafe.FinishWrite(int bytesWritten, OperationException error) } } } - - internal interface INativeUnsafe - { - IntPtr UnsafeHandle { get; } - - void FinishConnect(ConnectRequest request); - - uv_buf_t PrepareRead(ReadOperation readOperation); - - void FinishRead(ReadOperation readOperation); - - void FinishWrite(int bytesWritten, OperationException error); - } } diff --git a/src/DotNetty.Transport.Libuv/NativeChannel.cs b/src/DotNetty.Transport.Libuv/NativeChannel.cs index 46628a2df..412100ee4 100644 --- a/src/DotNetty.Transport.Libuv/NativeChannel.cs +++ b/src/DotNetty.Transport.Libuv/NativeChannel.cs @@ -28,17 +28,17 @@ namespace DotNetty.Transport.Libuv { - using System.Runtime.CompilerServices; using System.Net; + using System.Runtime.CompilerServices; using DotNetty.Common.Concurrency; using DotNetty.Transport.Channels; - using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Requests; public abstract partial class NativeChannel : AbstractChannel, INativeChannel where TChannel : NativeChannel where TUnsafe : NativeChannel.NativeChannelUnsafe, new() { - internal bool ReadPending; private volatile int v_state; @@ -55,7 +55,7 @@ protected NativeChannel(IChannel parent) : base(parent) public override bool IsActive => IsInState(StateFlags.Active); - protected override bool IsCompatible(IEventLoop eventLoop) => eventLoop is LoopExecutor; + protected override bool IsCompatible(IEventLoop eventLoop) => eventLoop is AbstractUVEventLoop; [MethodImpl(InlineMethod.AggressiveOptimization)] protected bool IsInState(int stateToCheck) => (v_state & stateToCheck) == stateToCheck; @@ -84,9 +84,9 @@ protected bool TryResetState(int stateToReset) return false; } - void DoConnect(EndPoint remoteAddress, EndPoint localAddress) + protected virtual void DoConnect(EndPoint remoteAddress, EndPoint localAddress) { - ConnectRequest request = null; + TcpConnect request = null; try { if (localAddress is object) @@ -123,8 +123,8 @@ protected virtual void OnConnected() protected abstract void DoStopRead(); - NativeHandle INativeChannel.GetHandle() => GetHandle(); - internal abstract NativeHandle GetHandle(); + IInternalScheduleHandle INativeChannel.GetHandle() => GetHandle(); + internal abstract IInternalScheduleHandle GetHandle(); bool INativeChannel.IsBound => IsBound; internal abstract bool IsBound { get; } diff --git a/src/DotNetty.NetUV/Requests/AddressInfoRequest.cs b/src/DotNetty.Transport.Libuv/Requests/AddressInfoRequest.cs similarity index 92% rename from src/DotNetty.NetUV/Requests/AddressInfoRequest.cs rename to src/DotNetty.Transport.Libuv/Requests/AddressInfoRequest.cs index da420d431..6c72134ac 100644 --- a/src/DotNetty.NetUV/Requests/AddressInfoRequest.cs +++ b/src/DotNetty.Transport.Libuv/Requests/AddressInfoRequest.cs @@ -12,14 +12,14 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; using System.Collections.Generic; using System.Net; using System.Runtime.CompilerServices; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; public readonly struct AddressInfo { @@ -56,10 +56,7 @@ internal unsafe AddressInfoRequest(LoopContext loop) internal override IntPtr InternalHandle => _handle.Handle; - public unsafe AddressInfoRequest Start( - string node, - string service, - Action callback) + public unsafe AddressInfoRequest Start(string node, string service, Action callback) { if (string.IsNullOrEmpty(node)) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.node); } if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } @@ -85,13 +82,13 @@ private void OnAddressInfoCallback(int status, ref addrinfo res) { OperationException error = null; IPHostEntry hostEntry = null; - if ((uint)status > SharedConstants.TooBigOrNegative) // < 0 + if (SharedConstants.TooBigOrNegative >= (uint)status) { - error = NativeMethods.CreateError((uv_err_code)status); + hostEntry = GetHostEntry(ref res); } else { - hostEntry = GetHostEntry(ref res); + error = NativeMethods.CreateError((uv_err_code)status); } var addressInfo = new AddressInfo(hostEntry, error); diff --git a/src/DotNetty.Transport.Libuv/Native/ConnectRequest.cs b/src/DotNetty.Transport.Libuv/Requests/ConnectRequest.cs similarity index 90% rename from src/DotNetty.Transport.Libuv/Native/ConnectRequest.cs rename to src/DotNetty.Transport.Libuv/Requests/ConnectRequest.cs index cb8c7a4e5..2b568b132 100644 --- a/src/DotNetty.Transport.Libuv/Native/ConnectRequest.cs +++ b/src/DotNetty.Transport.Libuv/Requests/ConnectRequest.cs @@ -26,11 +26,12 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.Transport.Libuv.Native +namespace DotNetty.Transport.Libuv.Requests { using System; + using DotNetty.Transport.Libuv.Native; - abstract class ConnectRequest : NativeRequest + internal abstract class ConnectRequest : IDisposable { protected static readonly uv_watcher_cb WatcherCallback = (h, s) => OnWatcherCallback(h, s); @@ -53,5 +54,7 @@ static void OnWatcherCallback(IntPtr handle, int status) } request.OnWatcherCallback(); } + + public abstract void Dispose(); } } diff --git a/src/DotNetty.NetUV/Handles/HandleExtensions.cs b/src/DotNetty.Transport.Libuv/Requests/HandleExtensions.cs similarity index 81% rename from src/DotNetty.NetUV/Handles/HandleExtensions.cs rename to src/DotNetty.Transport.Libuv/Requests/HandleExtensions.cs index 279a82af7..6a32232db 100644 --- a/src/DotNetty.NetUV/Handles/HandleExtensions.cs +++ b/src/DotNetty.Transport.Libuv/Requests/HandleExtensions.cs @@ -12,18 +12,17 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Handles +namespace DotNetty.Transport.Libuv.Handles { using System; using System.Net; - using DotNetty.NetUV.Requests; + using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Requests; public static class HandleExtensions { public static Pipe Listen(this Pipe pipe, - string name, - Action onConnection, - int backlog = ServerStream.DefaultBacklog) + string name, Action onConnection, int backlog = ServerStream.DefaultBacklog) { if (pipe is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.pipe); } if (string.IsNullOrEmpty(name)) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); } @@ -37,8 +36,7 @@ public static Pipe Listen(this Pipe pipe, } public static Pipe ConnectTo(this Pipe pipe, - string remoteName, - Action connectedAction) + string remoteName, Action connectedAction) { if (pipe is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.pipe); } if (string.IsNullOrEmpty(remoteName)) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.remoteName); } @@ -59,10 +57,7 @@ public static Pipe ConnectTo(this Pipe pipe, } public static Tcp Listen(this Tcp tcp, - IPEndPoint localEndPoint, - Action onConnection, - int backlog = ServerStream.DefaultBacklog, - bool dualStack = false) + IPEndPoint localEndPoint, Action onConnection, int backlog = ServerStream.DefaultBacklog, bool dualStack = false) { if (tcp is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tcp); } if (localEndPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.localEndPoint); } @@ -75,10 +70,7 @@ public static Tcp Listen(this Tcp tcp, } public static Tcp ConnectTo(this Tcp tcp, - IPEndPoint localEndPoint, - IPEndPoint remoteEndPoint, - Action connectedAction, - bool dualStack = false) + IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, Action connectedAction, bool dualStack = false) { if (tcp is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tcp); } if (localEndPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.localEndPoint); } @@ -92,9 +84,7 @@ public static Tcp ConnectTo(this Tcp tcp, } public static Tcp ConnectTo(this Tcp tcp, - IPEndPoint remoteEndPoint, - Action connectedAction, - bool dualStack = false) + IPEndPoint remoteEndPoint, Action connectedAction, bool dualStack = false) { if (tcp is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tcp); } if (remoteEndPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.remoteEndPoint); } @@ -115,9 +105,7 @@ public static Tcp ConnectTo(this Tcp tcp, } public static Tcp Bind(this Tcp tcp, - IPEndPoint localEndPoint, - Action onRead, - bool dualStack = false) + IPEndPoint localEndPoint, Action onRead, bool dualStack = false) { if (tcp is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tcp); } if (localEndPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.localEndPoint); } @@ -130,9 +118,7 @@ public static Tcp Bind(this Tcp tcp, } public static Udp ReceiveStart(this Udp udp, - IPEndPoint localEndPoint, - Action receiveAction, - bool dualStack = false) + IPEndPoint localEndPoint, Action receiveAction, bool dualStack = false) { if (udp is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.udp); } if (localEndPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.localEndPoint); } @@ -145,8 +131,7 @@ public static Udp ReceiveStart(this Udp udp, return udp; } - public static Udp ReceiveStart(this Udp udp, - Action receiveAction) + public static Udp ReceiveStart(this Udp udp, Action receiveAction) { if (udp is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.udp); } if (receiveAction is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.receiveAction); } diff --git a/src/DotNetty.NetUV/Requests/NameInfoRequest.cs b/src/DotNetty.Transport.Libuv/Requests/NameInfoRequest.cs similarity index 92% rename from src/DotNetty.NetUV/Requests/NameInfoRequest.cs rename to src/DotNetty.Transport.Libuv/Requests/NameInfoRequest.cs index d5d7d481b..c2e1e078b 100644 --- a/src/DotNetty.NetUV/Requests/NameInfoRequest.cs +++ b/src/DotNetty.Transport.Libuv/Requests/NameInfoRequest.cs @@ -12,12 +12,12 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; [Flags] public enum NameInfoFlags @@ -69,10 +69,8 @@ internal unsafe NameInfoRequest(LoopContext loop) internal override IntPtr InternalHandle => _handle.Handle; - public unsafe NameInfoRequest Start( - IPEndPoint endPoint, - Action callback, - NameInfoFlags flags = NameInfoFlags.None) + public unsafe NameInfoRequest Start(IPEndPoint endPoint, + Action callback, NameInfoFlags flags = NameInfoFlags.None) { if (endPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.endPoint); } if (callback is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callback); } diff --git a/src/DotNetty.NetUV/Requests/PipeConnect.cs b/src/DotNetty.Transport.Libuv/Requests/PipeConnect.cs similarity index 95% rename from src/DotNetty.NetUV/Requests/PipeConnect.cs rename to src/DotNetty.Transport.Libuv/Requests/PipeConnect.cs index c5be470dc..fd65c3c79 100644 --- a/src/DotNetty.NetUV/Requests/PipeConnect.cs +++ b/src/DotNetty.Transport.Libuv/Requests/PipeConnect.cs @@ -12,12 +12,12 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; using System.Runtime.CompilerServices; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; internal sealed class PipeConnect : IDisposable { diff --git a/src/DotNetty.Transport.Libuv/Requests/PipeListener.cs b/src/DotNetty.Transport.Libuv/Requests/PipeListener.cs new file mode 100644 index 000000000..cd3a83ab2 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Requests/PipeListener.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; +using DotNetty.Transport.Libuv.Handles; +using DotNetty.Transport.Libuv.Native; + +namespace DotNetty.Transport.Libuv.Requests +{ + internal sealed class PipeListener : IDisposable + { + private readonly List _pipes; + private readonly WindowsApi _windowsApi; + + public PipeListener() + { + _pipes = new List(); + _windowsApi = new WindowsApi(); + } + + + + public void Dispose() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/DotNetty.NetUV/Requests/RequestContext.cs b/src/DotNetty.Transport.Libuv/Requests/RequestContext.cs similarity index 89% rename from src/DotNetty.NetUV/Requests/RequestContext.cs rename to src/DotNetty.Transport.Libuv/Requests/RequestContext.cs index a3056a800..18db0548e 100644 --- a/src/DotNetty.NetUV/Requests/RequestContext.cs +++ b/src/DotNetty.Transport.Libuv/Requests/RequestContext.cs @@ -12,23 +12,20 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; internal sealed unsafe class RequestContext : NativeHandle { private readonly uv_req_type _requestType; private readonly int _handleSize; - internal RequestContext( - uv_req_type requestType, - int size, - ScheduleRequest target) + internal RequestContext(uv_req_type requestType, int size, ScheduleRequest target) { Debug.Assert(size >= 0); Debug.Assert(target is object); @@ -50,10 +47,7 @@ internal RequestContext( #endif } - internal RequestContext( - uv_req_type requestType, - Action initializer, - ScheduleRequest target) + internal RequestContext(uv_req_type requestType, Action initializer, ScheduleRequest target) { Debug.Assert(initializer is object); Debug.Assert(target is object); @@ -110,10 +104,7 @@ internal static T GetTarget(IntPtr handle) protected override void CloseHandle() { IntPtr handle = Handle; - if (handle == IntPtr.Zero) - { - return; - } + if (handle == IntPtr.Zero) { return; } IntPtr pHandle = ((uv_req_t*)handle)->data; diff --git a/src/DotNetty.NetUV/Requests/ScheduleRequest.cs b/src/DotNetty.Transport.Libuv/Requests/ScheduleRequest.cs similarity index 94% rename from src/DotNetty.NetUV/Requests/ScheduleRequest.cs rename to src/DotNetty.Transport.Libuv/Requests/ScheduleRequest.cs index 4eb141a60..1fb279627 100644 --- a/src/DotNetty.NetUV/Requests/ScheduleRequest.cs +++ b/src/DotNetty.Transport.Libuv/Requests/ScheduleRequest.cs @@ -12,11 +12,11 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; using DotNetty.Common.Internal.Logging; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; public abstract class ScheduleRequest : IDisposable { diff --git a/src/DotNetty.NetUV/Requests/StreamShutdown.cs b/src/DotNetty.Transport.Libuv/Requests/StreamShutdown.cs similarity index 75% rename from src/DotNetty.NetUV/Requests/StreamShutdown.cs rename to src/DotNetty.Transport.Libuv/Requests/StreamShutdown.cs index d08d3f508..a1a6d7ce5 100644 --- a/src/DotNetty.NetUV/Requests/StreamShutdown.cs +++ b/src/DotNetty.Transport.Libuv/Requests/StreamShutdown.cs @@ -12,19 +12,20 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; - internal sealed class StreamShutdown : IDisposable + internal sealed class StreamShutdown : IDisposable + where THandle : class, IInternalStreamHandle { private readonly WatcherRequest _watcherRequest; - private StreamHandle _streamHandle; - private Action _completedAction; + private THandle _streamHandle; + private Action _completedAction; - internal StreamShutdown(StreamHandle streamHandle, Action completedAction) + internal StreamShutdown(THandle streamHandle, Action completedAction) { if (streamHandle is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.streamHandle); } @@ -40,7 +41,7 @@ internal StreamShutdown(StreamHandle streamHandle, Action completion, StreamHandle handle, Exception error) + internal static void Completed(Action completion, THandle handle, Exception error) { if (handle is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.handle); } diff --git a/src/DotNetty.NetUV/Requests/TcpConnect.cs b/src/DotNetty.Transport.Libuv/Requests/TcpConnect.cs similarity index 71% rename from src/DotNetty.NetUV/Requests/TcpConnect.cs rename to src/DotNetty.Transport.Libuv/Requests/TcpConnect.cs index d96c35ed0..605701e68 100644 --- a/src/DotNetty.NetUV/Requests/TcpConnect.cs +++ b/src/DotNetty.Transport.Libuv/Requests/TcpConnect.cs @@ -12,29 +12,44 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; using System.Net; using System.Runtime.CompilerServices; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; internal sealed class TcpConnect : IDisposable { - private readonly WatcherRequest _watcherRequest; - private Action _connectedAction; + private WatcherRequest _watcherRequest; + private Action _connectedAction; - public TcpConnect(Tcp tcp, IPEndPoint remoteEndPoint, Action connectedAction) + public TcpConnect(Tcp tcp, IPEndPoint remoteEndPoint, Action connectedAction) + { + if (connectedAction is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.connectedAction); } + + _connectedAction = connectedAction; + Initialize(tcp, remoteEndPoint); + } + + public TcpConnect(INativeChannelUnsafe channelUnsafe, IPEndPoint remoteEndPoint) + { + if (channelUnsafe is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.channelUnsafe); } + + var tcp = channelUnsafe.UnsafeHandle as Tcp; + _connectedAction = (t, e) => channelUnsafe.FinishConnect(t, e); + Initialize(tcp, remoteEndPoint); + } + + private void Initialize(Tcp tcp, IPEndPoint remoteEndPoint) { if (tcp is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tcp); } if (remoteEndPoint is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.remoteEndPoint); } - if (connectedAction is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.connectedAction); } tcp.Validate(); Tcp = tcp; - _connectedAction = connectedAction; _watcherRequest = new WatcherRequest( uv_req_type.UV_CONNECT, (r, e) => OnConnected(e), @@ -43,7 +58,7 @@ public TcpConnect(Tcp tcp, IPEndPoint remoteEndPoint, Action con internal Tcp Tcp { get; private set; } - private void OnConnected(/*WatcherRequest request, */Exception error) + private void OnConnected(/*WatcherRequest request, */OperationException error) { if (Tcp is null || _connectedAction is null) { diff --git a/src/DotNetty.NetUV/Requests/WatcherRequest.cs b/src/DotNetty.Transport.Libuv/Requests/WatcherRequest.cs similarity index 82% rename from src/DotNetty.NetUV/Requests/WatcherRequest.cs rename to src/DotNetty.Transport.Libuv/Requests/WatcherRequest.cs index 1802701ab..84191beb9 100644 --- a/src/DotNetty.NetUV/Requests/WatcherRequest.cs +++ b/src/DotNetty.Transport.Libuv/Requests/WatcherRequest.cs @@ -12,11 +12,11 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; using System.Diagnostics; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; public sealed class WatcherRequest : ScheduleRequest { @@ -24,13 +24,11 @@ public sealed class WatcherRequest : ScheduleRequest private readonly RequestContext _handle; private readonly bool _closeOnCallback; - private Action _watcherCallback; + private Action _watcherCallback; - internal WatcherRequest( - uv_req_type requestType, - Action watcherCallback, - int size = 0, - bool closeOnCallback = false) + internal WatcherRequest(uv_req_type requestType, + Action watcherCallback, + int size = 0, bool closeOnCallback = false) : base(requestType) { Debug.Assert(size >= 0); @@ -40,11 +38,9 @@ internal WatcherRequest( _handle = new RequestContext(requestType, size, this); } - internal WatcherRequest( - uv_req_type requestType, - Action watcherCallback, - Action initializer, - bool closeOnCallback = false) + internal WatcherRequest(uv_req_type requestType, + Action watcherCallback, + Action initializer, bool closeOnCallback = false) : base(requestType) { Debug.Assert(initializer is object); diff --git a/src/DotNetty.NetUV/Requests/Work.cs b/src/DotNetty.Transport.Libuv/Requests/Work.cs similarity index 92% rename from src/DotNetty.NetUV/Requests/Work.cs rename to src/DotNetty.Transport.Libuv/Requests/Work.cs index e3deea2cf..1941da2b3 100644 --- a/src/DotNetty.NetUV/Requests/Work.cs +++ b/src/DotNetty.Transport.Libuv/Requests/Work.cs @@ -12,11 +12,11 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; public sealed class Work : ScheduleRequest { @@ -27,10 +27,7 @@ public sealed class Work : ScheduleRequest private Action _workCallback; private Action _afterWorkCallback; - internal Work( - LoopContext loop, - Action workCallback, - Action afterWorkCallback) + internal Work(LoopContext loop, Action workCallback, Action afterWorkCallback) : base(uv_req_type.UV_WORK) { if (loop is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.loop); } diff --git a/src/DotNetty.NetUV/Requests/WriteRequest.cs b/src/DotNetty.Transport.Libuv/Requests/WriteRequest.cs similarity index 90% rename from src/DotNetty.NetUV/Requests/WriteRequest.cs rename to src/DotNetty.Transport.Libuv/Requests/WriteRequest.cs index 02ec39d25..1211eca85 100644 --- a/src/DotNetty.NetUV/Requests/WriteRequest.cs +++ b/src/DotNetty.Transport.Libuv/Requests/WriteRequest.cs @@ -12,7 +12,7 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -namespace DotNetty.NetUV.Requests +namespace DotNetty.Transport.Libuv.Requests { using System; using System.Collections.Generic; @@ -21,7 +21,7 @@ namespace DotNetty.NetUV.Requests using System.Runtime.InteropServices; using DotNetty.Buffers; using DotNetty.Common; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Native; internal sealed class WriteRequest : ScheduleRequest { @@ -53,7 +53,7 @@ internal WriteRequest(uv_req_type requestType, ThreadLocalPool.Handle recyclerHa _recyclerHandle = recyclerHandle; _handles = new List(); - IntPtr addr = _requestContext.Handle; + var addr = _requestContext.Handle; _bufs = addr + _requestContext.HandleSize; _pin = GCHandle.Alloc(addr, GCHandleType.Pinned); _count = 0; @@ -77,7 +77,7 @@ internal void Prepare(IByteBuffer buf, Action callback) _completion = callback; int len = buf.ReadableBytes; - IntPtr addr = IntPtr.Zero; + var addr = IntPtr.Zero; if (buf.HasMemoryAddress) { addr = buf.AddressOfPinnedMemory(); @@ -91,7 +91,7 @@ internal void Prepare(IByteBuffer buf, Action callback) if (buf.IsSingleIoBuffer) { - ArraySegment arraySegment = buf.GetIoBuffer(); + var arraySegment = buf.GetIoBuffer(); byte[] array = arraySegment.Array; GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); @@ -102,13 +102,13 @@ internal void Prepare(IByteBuffer buf, Action callback) return; } - ArraySegment[] segments = buf.GetIoBuffers(); + var segments = buf.GetIoBuffers(); if (segments.Length <= MaximumLimit) { for (int i = 0; i < segments.Length; i++) { var segment = segments[i]; - GCHandle handle = GCHandle.Alloc(segment.Array, GCHandleType.Pinned); + var handle = GCHandle.Alloc(segment.Array, GCHandleType.Pinned); _handles.Add(handle); addr = handle.AddrOfPinnedObject(); @@ -118,13 +118,13 @@ internal void Prepare(IByteBuffer buf, Action callback) } _bufsArray = new uv_buf_t[segments.Length]; - GCHandle bufsPin = GCHandle.Alloc(_bufsArray, GCHandleType.Pinned); + var bufsPin = GCHandle.Alloc(_bufsArray, GCHandleType.Pinned); _handles.Add(bufsPin); for (int i = 0; i < segments.Length; i++) { var segment = segments[i]; - GCHandle handle = GCHandle.Alloc(segment.Array, GCHandleType.Pinned); + var handle = GCHandle.Alloc(segment.Array, GCHandleType.Pinned); _handles.Add(handle); addr = handle.AddrOfPinnedObject(); @@ -146,7 +146,7 @@ static InvalidOperationException GetInvalidOperationException() private void Add(IntPtr addr, int offset, int len) { - IntPtr baseOffset = _bufs + BufferSize * _count; + var baseOffset = _bufs + BufferSize * _count; ++_count; uv_buf_t.InitMemory(baseOffset, addr + offset, len); } @@ -203,7 +203,7 @@ private void OnWriteCallback(int status) error = NativeMethods.CreateError((uv_err_code)status); } - Action callback = _completion; + var callback = _completion; Release(); callback?.Invoke(this, error); } diff --git a/src/DotNetty.Transport.Libuv/TcpChannel.Unsafe.cs b/src/DotNetty.Transport.Libuv/TcpChannel.Unsafe.cs index 7bc2b93ca..e8dc9d654 100644 --- a/src/DotNetty.Transport.Libuv/TcpChannel.Unsafe.cs +++ b/src/DotNetty.Transport.Libuv/TcpChannel.Unsafe.cs @@ -28,17 +28,15 @@ namespace DotNetty.Transport.Libuv { - using System; + using DotNetty.Transport.Libuv.Handles; partial class TcpChannel { public sealed class TcpChannelUnsafe : NativeChannelUnsafe { - public TcpChannelUnsafe() : base() - { - } + public TcpChannelUnsafe() : base() { } - public override IntPtr UnsafeHandle => _channel._tcp.Handle; + public override IScheduleHandle UnsafeHandle => _channel._tcp; } } } diff --git a/src/DotNetty.Transport.Libuv/TcpChannel.cs b/src/DotNetty.Transport.Libuv/TcpChannel.cs index be715e355..07028ad4b 100644 --- a/src/DotNetty.Transport.Libuv/TcpChannel.cs +++ b/src/DotNetty.Transport.Libuv/TcpChannel.cs @@ -30,7 +30,8 @@ namespace DotNetty.Transport.Libuv { using System.Net; using DotNetty.Transport.Channels; - using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Requests; public sealed class TcpChannel : TcpChannel { @@ -71,8 +72,8 @@ protected override void DoRegister() { if (_tcp is null) { - var loopExecutor = (LoopExecutor)EventLoop; - _tcp = new Tcp(loopExecutor.UnsafeLoop); + var loopExecutor = (AbstractUVEventLoop)EventLoop; + _tcp = loopExecutor.UnsafeLoop.CreateTcp(); } else { @@ -80,7 +81,7 @@ protected override void DoRegister() } } - internal override NativeHandle GetHandle() + internal override IInternalScheduleHandle GetHandle() { if (_tcp is null) { @@ -120,12 +121,13 @@ protected override void DoClose() { if (TryResetState(StateFlags.Open | StateFlags.Active)) { - if (_tcp is object) + var tcp = _tcp; + if (tcp is not null) { - _tcp.ReadStop(); - _tcp.CloseHandle(); + _tcp = null; + tcp.ReadStop(); + tcp.CloseHandle(); } - _tcp = null; } } finally @@ -136,10 +138,7 @@ protected override void DoClose() protected override void DoBeginRead() { - if (!IsOpen) - { - return; - } + if (!IsOpen) { return; } ReadPending = true; if (!IsInState(StateFlags.ReadScheduled)) @@ -168,7 +167,7 @@ protected override void DoWrite(ChannelOutboundBuffer input) if (input.Size > 0) { SetState(StateFlags.WriteScheduled); - var loopExecutor = (LoopExecutor)EventLoop; + var loopExecutor = (AbstractUVEventLoop)EventLoop; WriteRequest request = loopExecutor.WriteRequestPool.Take(); request.DoWrite(Unsafe, input); } diff --git a/src/DotNetty.Transport.Libuv/TcpChannelConfig.cs b/src/DotNetty.Transport.Libuv/TcpChannelConfig.cs index 6cfbf7622..d6af9cfb4 100644 --- a/src/DotNetty.Transport.Libuv/TcpChannelConfig.cs +++ b/src/DotNetty.Transport.Libuv/TcpChannelConfig.cs @@ -33,11 +33,12 @@ namespace DotNetty.Transport.Libuv using System.Diagnostics; using System.Net.Sockets; using DotNetty.Transport.Channels; + using DotNetty.Transport.Libuv.Handles; using DotNetty.Transport.Libuv.Native; sealed class TcpChannelConfig : DefaultChannelConfiguration { - readonly Dictionary options; + readonly Dictionary _options; public TcpChannelConfig(IChannel channel) : base(channel) { @@ -50,7 +51,7 @@ public TcpChannelConfig(IChannel channel) : base(channel) // // - this.options = new Dictionary(5, ChannelOptionComparer.Default) + _options = new Dictionary(5, ChannelOptionComparer.Default) { { ChannelOption.TcpNodelay, 1 } // TCP_NODELAY by default }; @@ -60,23 +61,23 @@ public override T GetOption(ChannelOption option) { if (ChannelOption.SoRcvbuf.Equals(option)) { - return (T)(object)this.GetReceiveBufferSize(); + return (T)(object)GetReceiveBufferSize(); } if (ChannelOption.SoSndbuf.Equals(option)) { - return (T)(object)this.GetSendBufferSize(); + return (T)(object)GetSendBufferSize(); } if (ChannelOption.TcpNodelay.Equals(option)) { - return (T)(object)this.GetTcpNoDelay(); + return (T)(object)GetTcpNoDelay(); } if (ChannelOption.SoKeepalive.Equals(option)) { - return (T)(object)this.GetKeepAlive(); + return (T)(object)GetKeepAlive(); } if (ChannelOption.SoReuseaddr.Equals(option)) { - return (T)(object)this.GetReuseAddress(); + return (T)(object)GetReuseAddress(); } return base.GetOption(option); @@ -91,23 +92,23 @@ public override bool SetOption(ChannelOption option, T value) if (ChannelOption.SoRcvbuf.Equals(option)) { - this.SetReceiveBufferSize((int)(object)value); + SetReceiveBufferSize((int)(object)value); } else if (ChannelOption.SoSndbuf.Equals(option)) { - this.SetSendBufferSize((int)(object)value); + SetSendBufferSize((int)(object)value); } else if (ChannelOption.TcpNodelay.Equals(option)) { - this.SetTcpNoDelay((bool)(object)value); + SetTcpNoDelay((bool)(object)value); } else if (ChannelOption.SoKeepalive.Equals(option)) { - this.SetKeepAlive((bool)(object)value); + SetKeepAlive((bool)(object)value); } else if (ChannelOption.SoReuseaddr.Equals(option)) { - this.SetReuseAddress((bool)(object)value); + SetReuseAddress((bool)(object)value); } else { @@ -121,9 +122,9 @@ int GetReceiveBufferSize() { try { - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; var tcp = (Tcp)channel.GetHandle(); - return tcp.ReceiveBufferSize(0); + return tcp.GetReceiveBufferSize(); } catch (ObjectDisposedException ex) { @@ -138,17 +139,17 @@ int GetReceiveBufferSize() void SetReceiveBufferSize(int value) { - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; if (!channel.IsBound) { // Defer until bound - if (!this.options.ContainsKey(ChannelOption.SoRcvbuf)) + if (!_options.ContainsKey(ChannelOption.SoRcvbuf)) { - this.options.Add(ChannelOption.SoRcvbuf, value); + _options.Add(ChannelOption.SoRcvbuf, value); } else { - this.options[ChannelOption.SoRcvbuf] = value; + _options[ChannelOption.SoRcvbuf] = value; } } else @@ -157,11 +158,11 @@ void SetReceiveBufferSize(int value) } } - static void SetReceiveBufferSize(Tcp tcpHandle, int value) + static void SetReceiveBufferSize(Tcp tcp, int value) { try { - _ = tcpHandle.ReceiveBufferSize(value); + _ = tcp.SetReceiveBufferSize(value); } catch (ObjectDisposedException ex) { @@ -177,9 +178,9 @@ int GetSendBufferSize() { try { - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; var tcp = (Tcp)channel.GetHandle(); - return tcp.SendBufferSize(0); + return tcp.GetSendBufferSize(); } catch (ObjectDisposedException ex) { @@ -194,17 +195,17 @@ int GetSendBufferSize() void SetSendBufferSize(int value) { - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; if (!channel.IsBound) { // Defer until bound - if (!this.options.ContainsKey(ChannelOption.SoSndbuf)) + if (!_options.ContainsKey(ChannelOption.SoSndbuf)) { - this.options.Add(ChannelOption.SoSndbuf, value); + _options.Add(ChannelOption.SoSndbuf, value); } else { - this.options[ChannelOption.SoSndbuf] = value; + _options[ChannelOption.SoSndbuf] = value; } } else @@ -213,11 +214,11 @@ void SetSendBufferSize(int value) } } - static void SetSendBufferSize(Tcp tcpHandle, int value) + static void SetSendBufferSize(Tcp tcp, int value) { try { - _ = tcpHandle.SendBufferSize(value); + _ = tcp.SetSendBufferSize(value); } catch (ObjectDisposedException ex) { @@ -231,7 +232,7 @@ static void SetSendBufferSize(Tcp tcpHandle, int value) bool GetTcpNoDelay() { - if (this.options.TryGetValue(ChannelOption.TcpNodelay, out int value)) + if (_options.TryGetValue(ChannelOption.TcpNodelay, out int value)) { return value != 0; } @@ -240,31 +241,31 @@ bool GetTcpNoDelay() void SetTcpNoDelay(bool value) { - int optionValue = value ? 1 : 0; - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; if (!channel.IsBound) { + int optionValue = value ? 1 : 0; // Defer until bound - if (!this.options.ContainsKey(ChannelOption.TcpNodelay)) + if (!_options.ContainsKey(ChannelOption.TcpNodelay)) { - this.options.Add(ChannelOption.TcpNodelay, optionValue); + _options.Add(ChannelOption.TcpNodelay, optionValue); } else { - this.options[ChannelOption.TcpNodelay] = optionValue; + _options[ChannelOption.TcpNodelay] = optionValue; } } else { - SetTcpNoDelay((Tcp)channel.GetHandle(), optionValue); + SetTcpNoDelay((Tcp)channel.GetHandle(), value); } } - static void SetTcpNoDelay(Tcp tcpHandle, int value) + static void SetTcpNoDelay(Tcp tcp, bool value) { try { - tcpHandle.NoDelay(value); + tcp.NoDelay(value); } catch (ObjectDisposedException ex) { @@ -278,7 +279,7 @@ static void SetTcpNoDelay(Tcp tcpHandle, int value) bool GetKeepAlive() { - if (this.options.TryGetValue(ChannelOption.SoKeepalive, out int value)) + if (_options.TryGetValue(ChannelOption.SoKeepalive, out int value)) { return value != 0; } @@ -287,31 +288,31 @@ bool GetKeepAlive() void SetKeepAlive(bool value) { - int optionValue = value ? 1 : 0; - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; if (!channel.IsBound) { + int optionValue = value ? 1 : 0; // Defer until bound - if (!this.options.ContainsKey(ChannelOption.SoKeepalive)) + if (!_options.ContainsKey(ChannelOption.SoKeepalive)) { - this.options.Add(ChannelOption.SoKeepalive, optionValue); + _options.Add(ChannelOption.SoKeepalive, optionValue); } else { - this.options[ChannelOption.SoKeepalive] = optionValue; + _options[ChannelOption.SoKeepalive] = optionValue; } } else { - SetKeepAlive((Tcp)channel.GetHandle(), optionValue); + SetKeepAlive((Tcp)channel.GetHandle(), value); } } - static void SetKeepAlive(Tcp tcpHandle, int value) + static void SetKeepAlive(Tcp tcp, bool value) { try { - tcpHandle.KeepAlive(value, 1 /* Delay in seconds to take effect*/); + tcp.KeepAlive(value, 1 /* Delay in seconds to take effect*/); } catch (ObjectDisposedException ex) { @@ -327,9 +328,9 @@ bool GetReuseAddress() { try { - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; var tcpListener = (Tcp)channel.GetHandle(); - return PlatformApi.GetReuseAddress(tcpListener); + return PlatformApis.GetReuseAddress(tcpListener); } catch (ObjectDisposedException ex) { @@ -345,17 +346,17 @@ bool GetReuseAddress() void SetReuseAddress(bool value) { int optionValue = value ? 1 : 0; - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; if (!channel.IsBound) { // Defer until registered - if (!this.options.ContainsKey(ChannelOption.SoReuseaddr)) + if (!_options.ContainsKey(ChannelOption.SoReuseaddr)) { - this.options.Add(ChannelOption.SoReuseaddr, optionValue); + _options.Add(ChannelOption.SoReuseaddr, optionValue); } else { - this.options[ChannelOption.SoReuseaddr] = optionValue; + _options[ChannelOption.SoReuseaddr] = optionValue; } } else @@ -368,7 +369,7 @@ static void SetReuseAddress(Tcp tcp, int value) { try { - PlatformApi.SetReuseAddress(tcp, value); + PlatformApis.SetReuseAddress(tcp, value); } catch (ObjectDisposedException ex) { @@ -385,31 +386,31 @@ static void SetReuseAddress(Tcp tcp, int value) // is not yet created, it is deferred until channel register. internal void Apply() { - Debug.Assert(this.options.Count <= 5); + Debug.Assert(_options.Count <= 5); - var channel = (INativeChannel)this.Channel; + var channel = (INativeChannel)Channel; var tcp = (Tcp)channel.GetHandle(); - foreach (ChannelOption option in this.options.Keys) + foreach (ChannelOption option in _options.Keys) { if (ChannelOption.SoRcvbuf.Equals(option)) { - SetReceiveBufferSize(tcp, this.options[ChannelOption.SoRcvbuf]); + SetReceiveBufferSize(tcp, _options[ChannelOption.SoRcvbuf]); } else if (ChannelOption.SoSndbuf.Equals(option)) { - SetSendBufferSize(tcp, this.options[ChannelOption.SoSndbuf]); + SetSendBufferSize(tcp, _options[ChannelOption.SoSndbuf]); } else if (ChannelOption.TcpNodelay.Equals(option)) { - SetTcpNoDelay(tcp, this.options[ChannelOption.TcpNodelay]); + SetTcpNoDelay(tcp, _options[ChannelOption.TcpNodelay] != 0); } else if (ChannelOption.SoKeepalive.Equals(option)) { - SetKeepAlive(tcp, this.options[ChannelOption.SoKeepalive]); + SetKeepAlive(tcp, _options[ChannelOption.SoKeepalive] != 0); } else if (ChannelOption.SoReuseaddr.Equals(option)) { - SetReuseAddress(tcp, this.options[ChannelOption.SoReuseaddr]); + SetReuseAddress(tcp, _options[ChannelOption.SoReuseaddr]); } else { diff --git a/src/DotNetty.Transport.Libuv/TcpChannelFactory.cs b/src/DotNetty.Transport.Libuv/TcpChannelFactory.cs index 26cf6380c..0df4f60a5 100644 --- a/src/DotNetty.Transport.Libuv/TcpChannelFactory.cs +++ b/src/DotNetty.Transport.Libuv/TcpChannelFactory.cs @@ -23,6 +23,7 @@ using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; using DotNetty.Transport.Libuv.Native; +using DotNetty.Transport.Libuv.Handles; namespace DotNetty.Transport.Libuv { diff --git a/src/DotNetty.Transport.Libuv/TcpServerChannel.Unsafe.cs b/src/DotNetty.Transport.Libuv/TcpServerChannel.Unsafe.cs index 305455c0b..2ccc21254 100644 --- a/src/DotNetty.Transport.Libuv/TcpServerChannel.Unsafe.cs +++ b/src/DotNetty.Transport.Libuv/TcpServerChannel.Unsafe.cs @@ -30,32 +30,24 @@ namespace DotNetty.Transport.Libuv { using System; using DotNetty.Transport.Channels; + using DotNetty.Transport.Libuv.Handles; using DotNetty.Transport.Libuv.Native; - internal interface IServerNativeUnsafe - { - void Accept(RemoteConnection connection); - - void Accept(NativeHandle handle); - } - partial class TcpServerChannel { public sealed class TcpServerChannelUnsafe : NativeChannelUnsafe, IServerNativeUnsafe { static readonly Action AcceptAction = (u, e) => OnAccept(u, e); - public TcpServerChannelUnsafe() : base() - { - } + public TcpServerChannelUnsafe() : base() { } - public override IntPtr UnsafeHandle => _channel._tcpListener.Handle; + public override IScheduleHandle UnsafeHandle => _channel._tcpListener.Handle; // Connection callback from Libuv thread void IServerNativeUnsafe.Accept(RemoteConnection connection) { var ch = _channel; - NativeHandle client = connection.Client; + var client = connection.Client; var connError = connection.Error; // If the AutoRead is false, reject the connection @@ -91,21 +83,21 @@ void IServerNativeUnsafe.Accept(RemoteConnection connection) } else { - Accept((Tcp)client); + Accept(client); } } // Called from other Libuv loop/thread received tcp handle from pipe - void IServerNativeUnsafe.Accept(NativeHandle handle) + void IServerNativeUnsafe.Accept(Tcp tcp) { var ch = _channel; if (ch.EventLoop.InEventLoop) { - Accept((Tcp)handle); + Accept(tcp); } else { - _channel.EventLoop.Execute(AcceptAction, this, handle); + _channel.EventLoop.Execute(AcceptAction, this, tcp); } } diff --git a/src/DotNetty.Transport.Libuv/TcpServerChannel.cs b/src/DotNetty.Transport.Libuv/TcpServerChannel.cs index a9f5539ef..ffee1ee75 100644 --- a/src/DotNetty.Transport.Libuv/TcpServerChannel.cs +++ b/src/DotNetty.Transport.Libuv/TcpServerChannel.cs @@ -33,7 +33,6 @@ namespace DotNetty.Transport.Libuv using System.Net; using DotNetty.Transport.Channels; using DotNetty.Transport.Libuv.Native; - using TcpListener = Native.TcpListener; public sealed class TcpServerChannel : TcpServerChannel { @@ -79,9 +78,9 @@ protected override void DoBind(EndPoint localAddress) if (!IsInState(StateFlags.Active)) { var address = (IPEndPoint)localAddress; - var loopExecutor = (LoopExecutor)EventLoop; + var loopExecutor = (AbstractUVEventLoop)EventLoop; - uint flags = PlatformApi.GetAddressFamily(address.AddressFamily); + uint flags = PlatformApis.GetAddressFamily(address.AddressFamily); _tcpListener = new TcpListener(loopExecutor.UnsafeLoop, flags); // Apply the configuration right after the tcp handle is created diff --git a/src/DotNetty.Transport.Libuv/TcpServerChannelConfig.cs b/src/DotNetty.Transport.Libuv/TcpServerChannelConfig.cs index 0f7b5205c..94665d370 100644 --- a/src/DotNetty.Transport.Libuv/TcpServerChannelConfig.cs +++ b/src/DotNetty.Transport.Libuv/TcpServerChannelConfig.cs @@ -33,10 +33,9 @@ namespace DotNetty.Transport.Libuv using System.Diagnostics; using System.Net.Sockets; using DotNetty.Transport.Channels; + using DotNetty.Transport.Libuv.Handles; using DotNetty.Transport.Libuv.Native; - using TcpListener = Native.TcpListener; - sealed class TcpServerChannelConfig : DefaultChannelConfiguration { const int DefaultBacklog = 200; @@ -116,8 +115,8 @@ int GetReceiveBufferSize() try { var channel = (INativeChannel)this.Channel; - var tcpListener = (TcpListener)channel.GetHandle(); - return tcpListener.ReceiveBufferSize(0); + var tcpListener = (Tcp)channel.GetHandle(); + return tcpListener.GetReceiveBufferSize(); } catch (ObjectDisposedException ex) { @@ -147,15 +146,15 @@ void SetReceiveBufferSize(int value) } else { - SetReceiveBufferSize((TcpHandle)channel.GetHandle(), value); + SetReceiveBufferSize((Tcp)channel.GetHandle(), value); } } - static void SetReceiveBufferSize(TcpHandle tcpHandle, int value) + static void SetReceiveBufferSize(Tcp tcpHandle, int value) { try { - _ = tcpHandle.ReceiveBufferSize(value); + _ = tcpHandle.SetReceiveBufferSize(value); } catch (ObjectDisposedException ex) { @@ -172,8 +171,8 @@ bool GetReuseAddress() try { var channel = (INativeChannel)this.Channel; - var tcpListener = (TcpListener)channel.GetHandle(); - return PlatformApi.GetReuseAddress(tcpListener); + var tcpListener = (Tcp)channel.GetHandle(); + return PlatformApis.GetReuseAddress(tcpListener); } catch (ObjectDisposedException ex) { @@ -204,15 +203,15 @@ void SetReuseAddress(bool value) } else { - SetReuseAddress((TcpListener)channel.GetHandle(), optionValue); + SetReuseAddress((Tcp)channel.GetHandle(), optionValue); } } - static void SetReuseAddress(TcpListener listener, int value) + static void SetReuseAddress(Tcp listener, int value) { try { - PlatformApi.SetReuseAddress(listener, value); + PlatformApis.SetReuseAddress(listener, value); } catch (ObjectDisposedException ex) { @@ -229,8 +228,8 @@ bool GetReusePort() try { var channel = (INativeChannel)this.Channel; - var tcpListener = (TcpListener)channel.GetHandle(); - return PlatformApi.GetReusePort(tcpListener); + var tcpListener = (Tcp)channel.GetHandle(); + return PlatformApis.GetReusePort(tcpListener); } catch (ObjectDisposedException ex) { @@ -261,15 +260,15 @@ void SetReusePort(bool value) } else { - SetReusePort((TcpListener)channel.GetHandle(), optionValue); + SetReusePort((Tcp)channel.GetHandle(), optionValue); } } - static void SetReusePort(TcpListener listener, int value) + static void SetReusePort(Tcp listener, int value) { try { - PlatformApi.SetReusePort(listener, value); + PlatformApis.SetReusePort(listener, value); } catch (ObjectDisposedException ex) { @@ -291,7 +290,7 @@ internal void Apply() Debug.Assert(this.options.Count <= 3); var channel = (INativeChannel)this.Channel; - var tcpListener = (TcpListener)channel.GetHandle(); + var tcpListener = (Tcp)channel.GetHandle(); foreach (ChannelOption option in this.options.Keys) { if (ChannelOption.SoRcvbuf.Equals(option)) diff --git a/src/DotNetty.Transport.Libuv/EventLoop.cs b/src/DotNetty.Transport.Libuv/UVEventLoop.cs similarity index 78% rename from src/DotNetty.Transport.Libuv/EventLoop.cs rename to src/DotNetty.Transport.Libuv/UVEventLoop.cs index d5c1cc70f..5b8b1ce9a 100644 --- a/src/DotNetty.Transport.Libuv/EventLoop.cs +++ b/src/DotNetty.Transport.Libuv/UVEventLoop.cs @@ -32,14 +32,14 @@ namespace DotNetty.Transport.Libuv using DotNetty.Common.Concurrency; using DotNetty.Transport.Channels; - public sealed class EventLoop : LoopExecutor + public sealed class UVEventLoop : AbstractUVEventLoop { - internal EventLoop(IEventLoopGroup parent) - : this(parent, DefaultThreadFactory.Instance, RejectedExecutionHandlers.Reject(), DefaultBreakoutInterval) + internal UVEventLoop(IEventLoopGroup parent) + : this(parent, DefaultThreadFactory.Instance, RejectedExecutionHandlers.Reject(), DefaultBreakoutInterval) { } - internal EventLoop(IEventLoopGroup parent, IThreadFactory threadFactory, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) + internal UVEventLoop(IEventLoopGroup parent, IThreadFactory threadFactory, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) : base(parent, threadFactory, rejectedHandler, breakoutInterval) { Start(); diff --git a/src/DotNetty.Transport.Libuv/EventLoopChooserFactory.cs b/src/DotNetty.Transport.Libuv/UVEventLoopChooserFactory.cs similarity index 92% rename from src/DotNetty.Transport.Libuv/EventLoopChooserFactory.cs rename to src/DotNetty.Transport.Libuv/UVEventLoopChooserFactory.cs index 975882532..89a5b302d 100644 --- a/src/DotNetty.Transport.Libuv/EventLoopChooserFactory.cs +++ b/src/DotNetty.Transport.Libuv/UVEventLoopChooserFactory.cs @@ -26,12 +26,12 @@ namespace DotNetty.Transport.Libuv using System.Threading; using DotNetty.Common.Concurrency; - internal sealed class EventLoopChooserFactory : IEventExecutorChooserFactory - where TEventLoop : LoopExecutor + internal sealed class UVEventLoopChooserFactory : IEventExecutorChooserFactory + where TEventLoop : AbstractUVEventLoop { - public static readonly EventLoopChooserFactory Instance = new EventLoopChooserFactory(); + public static readonly UVEventLoopChooserFactory Instance = new UVEventLoopChooserFactory(); - private EventLoopChooserFactory() { } + private UVEventLoopChooserFactory() { } public IEventExecutorChooser NewChooser(TEventLoop[] eventLoops) { diff --git a/src/DotNetty.Transport.Libuv/EventLoopGroup.cs b/src/DotNetty.Transport.Libuv/UVEventLoopGroup.cs similarity index 54% rename from src/DotNetty.Transport.Libuv/EventLoopGroup.cs rename to src/DotNetty.Transport.Libuv/UVEventLoopGroup.cs index 1a27d89a8..29d411582 100644 --- a/src/DotNetty.Transport.Libuv/EventLoopGroup.cs +++ b/src/DotNetty.Transport.Libuv/UVEventLoopGroup.cs @@ -31,81 +31,80 @@ namespace DotNetty.Transport.Libuv using System; using System.Threading.Tasks; using DotNetty.Common.Concurrency; + using DotNetty.Transport.Libuv.Handles; using DotNetty.Transport.Channels; - using DotNetty.Transport.Libuv.Native; - public sealed class EventLoopGroup : MultithreadEventLoopGroup + public sealed class UVEventLoopGroup : MultithreadEventLoopGroup { private static readonly int DefaultEventLoopCount; - private static readonly Func DefaultEventLoopFactory; + private static readonly Func DefaultEventLoopFactory; - static EventLoopGroup() + static UVEventLoopGroup() { DefaultEventLoopCount = Environment.ProcessorCount; - DefaultEventLoopFactory = group => new EventLoop(group); + DefaultEventLoopFactory = group => new UVEventLoop(group); } - public EventLoopGroup() + public UVEventLoopGroup() : this(0) { } - public EventLoopGroup(int nThreads) - : base(0u >= (uint)nThreads ? DefaultEventLoopCount : nThreads, EventLoopChooserFactory.Instance, DefaultEventLoopFactory) + public UVEventLoopGroup(int nThreads) + : base(0u >= (uint)nThreads ? DefaultEventLoopCount : nThreads, UVEventLoopChooserFactory.Instance, DefaultEventLoopFactory) { } - public EventLoopGroup(int nThreads, TimeSpan breakoutInterval) - : this(nThreads, DefaultThreadFactory.Instance, RejectedExecutionHandlers.Reject(), breakoutInterval) + public UVEventLoopGroup(int nThreads, TimeSpan breakoutInterval) + : this(nThreads, DefaultThreadFactory.Instance, RejectedExecutionHandlers.Reject(), breakoutInterval) { } - public EventLoopGroup(int nThreads, IRejectedExecutionHandler rejectedHandler) - : this(nThreads, rejectedHandler, LoopExecutor.DefaultBreakoutInterval) + public UVEventLoopGroup(int nThreads, IRejectedExecutionHandler rejectedHandler) + : this(nThreads, rejectedHandler, AbstractUVEventLoop.DefaultBreakoutInterval) { } - public EventLoopGroup(int nThreads, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) - : this(nThreads, DefaultThreadFactory.Instance, rejectedHandler, breakoutInterval) + public UVEventLoopGroup(int nThreads, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) + : this(nThreads, DefaultThreadFactory.Instance, rejectedHandler, breakoutInterval) { } - public EventLoopGroup(int nThreads, IThreadFactory threadFactory, TimeSpan breakoutInterval) + public UVEventLoopGroup(int nThreads, IThreadFactory threadFactory, TimeSpan breakoutInterval) : this(nThreads, threadFactory, RejectedExecutionHandlers.Reject(), breakoutInterval) { } - public EventLoopGroup(int nThreads, IThreadFactory threadFactory, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) + public UVEventLoopGroup(int nThreads, IThreadFactory threadFactory, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval) : base(0u >= (uint)nThreads ? DefaultEventLoopCount : nThreads, - EventLoopChooserFactory.Instance, - group => new EventLoop(group, threadFactory, rejectedHandler, breakoutInterval)) + UVEventLoopChooserFactory.Instance, + group => new UVEventLoop(group, threadFactory, rejectedHandler, breakoutInterval)) { } public override Task RegisterAsync(IChannel channel) { - var nativeChannel = channel as INativeChannel; - if (nativeChannel is null) + if (channel is not INativeChannel nativeChannel) { - ThrowHelper.ThrowArgumentException_RegChannel(); + return ThrowHelper.FromArgumentException_RegChannel(); } // The handle loop must be the same as the loop of the // handle was created from. - NativeHandle handle = nativeChannel.GetHandle(); - IntPtr loopHandle = handle.LoopHandle(); + var handle = nativeChannel.GetHandle(); + var loopHandle = ((IInternalStreamHandle)handle).LoopHandle(); var eventLoops = GetItems(); for (int i = 0; i < eventLoops.Count; i++) { var eventLoop = eventLoops[i]; - if (eventLoop.UnsafeLoop.Handle == loopHandle) + if (eventLoop.UnsafeLoop.InternalHandle == loopHandle) { return eventLoop.RegisterAsync(nativeChannel); } } - return ThrowHelper.ThrowInvalidOperationException(loopHandle); + return ThrowHelper.FromInvalidOperationException(loopHandle); } } } \ No newline at end of file diff --git a/src/DotNetty.Transport.Libuv/WorkerEventLoop.cs b/src/DotNetty.Transport.Libuv/WorkerEventLoop.cs index da6ee521e..a2673dd5b 100644 --- a/src/DotNetty.Transport.Libuv/WorkerEventLoop.cs +++ b/src/DotNetty.Transport.Libuv/WorkerEventLoop.cs @@ -32,9 +32,10 @@ namespace DotNetty.Transport.Libuv using System.Diagnostics; using System.Threading.Tasks; using DotNetty.Common.Concurrency; + using DotNetty.Transport.Libuv.Handles; using DotNetty.Transport.Libuv.Native; - public sealed class WorkerEventLoop : LoopExecutor + public sealed class WorkerEventLoop : AbstractUVEventLoop { private readonly Action _onReadAction; private readonly IPromise _connectCompletion; @@ -68,7 +69,7 @@ protected override void Initialize() { Debug.Assert(_pipe is null); - _pipe = new Pipe(UnsafeLoop, true); + _pipe = UnsafeLoop.CreatePipe(true); PipeConnect request = null; try { @@ -128,41 +129,41 @@ private void OnRead(Pipe handle, int status) } } - sealed class PipeConnect : ConnectRequest - { - const int MaximumRetryCount = 10; - - readonly WorkerEventLoop _workerEventLoop; - int _retryCount; - - public PipeConnect(WorkerEventLoop workerEventLoop) - { - Debug.Assert(workerEventLoop is object); - - _workerEventLoop = workerEventLoop; - Connect(); - _retryCount = 0; - } - - protected override void OnWatcherCallback() - { - if (Error is object && _retryCount < MaximumRetryCount) - { - if (Logger.InfoEnabled) Logger.FailedToConnectToDispatcher(_retryCount, Error); - Connect(); - _retryCount++; - } - else - { - _workerEventLoop.OnConnected(this); - } - } - - void Connect() => NativeMethods.uv_pipe_connect( - Handle, - _workerEventLoop._pipe.Handle, - _workerEventLoop._pipeName, - WatcherCallback); - } + //sealed class PipeConnect : ConnectRequest + //{ + // const int MaximumRetryCount = 10; + + // readonly WorkerEventLoop _workerEventLoop; + // int _retryCount; + + // public PipeConnect(WorkerEventLoop workerEventLoop) + // { + // Debug.Assert(workerEventLoop is object); + + // _workerEventLoop = workerEventLoop; + // Connect(); + // _retryCount = 0; + // } + + // protected override void OnWatcherCallback() + // { + // if (Error is object && _retryCount < MaximumRetryCount) + // { + // if (Logger.InfoEnabled) Logger.FailedToConnectToDispatcher(_retryCount, Error); + // Connect(); + // _retryCount++; + // } + // else + // { + // _workerEventLoop.OnConnected(this); + // } + // } + + // void Connect() => NativeMethods.uv_pipe_connect( + // Handle, + // _workerEventLoop._pipe.Handle, + // _workerEventLoop._pipeName, + // WatcherCallback); + //} } } \ No newline at end of file diff --git a/src/DotNetty.Transport.Libuv/WorkerEventLoopGroup.cs b/src/DotNetty.Transport.Libuv/WorkerEventLoopGroup.cs index e55d225b8..6ddf20ddb 100644 --- a/src/DotNetty.Transport.Libuv/WorkerEventLoopGroup.cs +++ b/src/DotNetty.Transport.Libuv/WorkerEventLoopGroup.cs @@ -36,7 +36,7 @@ namespace DotNetty.Transport.Libuv using DotNetty.Common; using DotNetty.Common.Concurrency; using DotNetty.Transport.Channels; - using DotNetty.Transport.Libuv.Native; + using DotNetty.Transport.Libuv.Handles; public sealed class WorkerEventLoopGroup : AbstractEventExecutorGroup, IEventLoopGroup { @@ -78,7 +78,7 @@ public WorkerEventLoopGroup(DispatcherEventLoopGroup eventLoopGroup, int nThread } public WorkerEventLoopGroup(DispatcherEventLoopGroup eventLoopGroup, int nThreads, IThreadFactory threadFactory, IRejectedExecutionHandler rejectedHandler) - : this(eventLoopGroup, nThreads, threadFactory, rejectedHandler, LoopExecutor.DefaultBreakoutInterval) + : this(eventLoopGroup, nThreads, threadFactory, rejectedHandler, AbstractUVEventLoop.DefaultBreakoutInterval) { } @@ -100,7 +100,7 @@ public WorkerEventLoopGroup(DispatcherEventLoopGroup eventLoopGroup, int nThread } public WorkerEventLoopGroup(DispatcherEventLoopGroup eventLoopGroup, int nThreads, IEventExecutorChooserFactory chooserFactory, IRejectedExecutionHandler rejectedHandler) - : this(eventLoopGroup, nThreads, chooserFactory, rejectedHandler, LoopExecutor.DefaultBreakoutInterval) + : this(eventLoopGroup, nThreads, chooserFactory, rejectedHandler, AbstractUVEventLoop.DefaultBreakoutInterval) { } @@ -162,7 +162,7 @@ public WorkerEventLoopGroup(DispatcherEventLoopGroup eventLoopGroup, int nThread internal string PipeName { get; } - internal void Accept(NativeHandle handle) + internal void Accept(Tcp handle) { Debug.Assert(_dispatcherLoop is object); _dispatcherLoop.Accept(handle); @@ -177,20 +177,20 @@ public Task RegisterAsync(IChannel channel) var nativeChannel = channel as INativeChannel; if (nativeChannel is null) { - ThrowHelper.ThrowArgumentException_RegChannel(); + return ThrowHelper.FromArgumentException_RegChannel(); } - NativeHandle handle = nativeChannel.GetHandle(); + var handle = (DotNetty.Transport.Libuv.Handles.IInternalScheduleHandle)nativeChannel.GetHandle(); IntPtr loopHandle = handle.LoopHandle(); for (int i = 0; i < _eventLoops.Length; i++) { - if (_eventLoops[i].UnsafeLoop.Handle == loopHandle) + if (_eventLoops[i].UnsafeLoop.InternalHandle == loopHandle) { return _eventLoops[i].RegisterAsync(nativeChannel); } } - return ThrowHelper.ThrowInvalidOperationException(loopHandle); + return ThrowHelper.FromInvalidOperationException(loopHandle); } public override Task ShutdownGracefullyAsync(TimeSpan quietPeriod, TimeSpan timeout) diff --git a/src/DotNetty.Transport/Channels/IChannelHandlerContextExtensions.cs b/src/DotNetty.Transport/Channels/IChannelHandlerContextExtensions.cs index 545ce0732..d88dfb91c 100644 --- a/src/DotNetty.Transport/Channels/IChannelHandlerContextExtensions.cs +++ b/src/DotNetty.Transport/Channels/IChannelHandlerContextExtensions.cs @@ -48,7 +48,7 @@ public static Task WriteAndFlushManyAsync(this IChannelHandlerContext context, I return writeCloseCompletion; } - private static readonly Action s_returnAfterWriteAction = (t, s) => ReturnAfterWriteAction(t, s); - private static void ReturnAfterWriteAction(Task t, object s) => ((ThreadLocalList)s).Return(); + private static readonly Action s_returnAfterWriteAction = (t, s) => ReturnAfterWriteAction(s); + private static void ReturnAfterWriteAction(object s) => ((ThreadLocalList)s).Return(); } } diff --git a/src/DotNetty.Transport/Channels/Sockets/PlatformApis.cs b/src/DotNetty.Transport/Channels/Sockets/PlatformApis.cs deleted file mode 100644 index cead53208..000000000 --- a/src/DotNetty.Transport/Channels/Sockets/PlatformApis.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Copyright (c) 2020 The Dotnetty-Span-Fork Project (cuteant@outlook.com) All rights reserved. - * - * https://github.com/cuteant/dotnetty-span-fork - * - * Licensed under the MIT license. See LICENSE file in the project root for full license information. - */ - -using System.Runtime.InteropServices; - -namespace DotNetty.Transport.Channels.Sockets -{ - internal static class PlatformApis - { - public static readonly bool IsWindows; - - public static readonly bool IsLinux; - - public static readonly bool IsDarwin; - - static PlatformApis() - { - IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); - IsDarwin = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); - } - } -} diff --git a/src/DotNetty.Transport/Channels/Sockets/SocketEx.cs b/src/DotNetty.Transport/Channels/Sockets/SocketEx.cs index 5827731a1..8cf0126b9 100644 --- a/src/DotNetty.Transport/Channels/Sockets/SocketEx.cs +++ b/src/DotNetty.Transport/Channels/Sockets/SocketEx.cs @@ -22,6 +22,7 @@ using System; using System.Net.Sockets; +using DotNetty.Common; namespace DotNetty.Transport.Channels.Sockets { @@ -94,7 +95,7 @@ public static void SafeClose(this Socket socket) /// Code take from Orleans(See https://github.com/dotnet/orleans/blob/main/src/Orleans.Core/Networking/Shared/SocketExtensions.cs). internal static void EnableFastpath(this Socket socket) { - if (!PlatformApis.IsWindows) { return; } + if (!Platform.IsWindows) { return; } const int SIO_LOOPBACK_FAST_PATH = -1744830448; try @@ -121,7 +122,7 @@ public static bool IsSocketAbortError(this SocketError errorCode) case SocketError.OperationAborted: case SocketError.Interrupted: // Calling Dispose after ReceiveAsync can cause an "InvalidArgument" error on *nix. - case SocketError.InvalidArgument when !PlatformApis.IsWindows: + case SocketError.InvalidArgument when !Platform.IsWindows: return true; default: @@ -136,9 +137,9 @@ public static bool IsSocketResetError(this SocketError errorCode) case SocketError.ConnectionReset: case SocketError.Shutdown: // A connection reset can be reported as SocketError.ConnectionAborted on Windows. - case SocketError.ConnectionAborted when PlatformApis.IsWindows: + case SocketError.ConnectionAborted when Platform.IsWindows: // ProtocolType can be removed once https://github.com/dotnet/corefx/issues/31927 is fixed. - case SocketError.ProtocolType when PlatformApis.IsDarwin: + case SocketError.ProtocolType when Platform.IsDarwin: return true; default: diff --git a/src/DotNetty.Transport/Channels/TaskExtensions.cs b/src/DotNetty.Transport/Channels/TaskExtensions.cs index a2c3447ec..38a049d9b 100644 --- a/src/DotNetty.Transport/Channels/TaskExtensions.cs +++ b/src/DotNetty.Transport/Channels/TaskExtensions.cs @@ -43,8 +43,8 @@ public static Task CloseOnComplete(this Task task, IChannel channel) return task.ContinueWith(CloseChannelOnCompleteAction, channel, TaskContinuationOptions.ExecuteSynchronously); } } - private static readonly Action CloseChannelOnCompleteAction = (t, s) => CloseChannelOnComplete(t, s); - private static void CloseChannelOnComplete(Task t, object c) => _ = ((IChannel)c).CloseAsync(); + private static readonly Action CloseChannelOnCompleteAction = (t, s) => CloseChannelOnComplete(s); + private static void CloseChannelOnComplete(object c) => _ = ((IChannel)c).CloseAsync(); [MethodImpl(InlineMethod.AggressiveOptimization)] @@ -60,8 +60,8 @@ public static Task CloseOnComplete(this Task task, IChannel channel, IPromise pr return task.ContinueWith(CloseWrappedChannelOnCompleteAction, (channel, promise), TaskContinuationOptions.ExecuteSynchronously); } } - private static readonly Action CloseWrappedChannelOnCompleteAction = (t, s) => CloseWrappedChannelOnComplete(t, s); - private static void CloseWrappedChannelOnComplete(Task t, object s) + private static readonly Action CloseWrappedChannelOnCompleteAction = (t, s) => CloseWrappedChannelOnComplete(s); + private static void CloseWrappedChannelOnComplete(object s) { var wrapped = ((IChannel, IPromise))s; _ = wrapped.Item1.CloseAsync(wrapped.Item2); @@ -81,8 +81,8 @@ public static Task CloseOnComplete(this Task task, IChannelHandlerContext ctx) return task.ContinueWith(CloseContextOnCompleteAction, ctx, TaskContinuationOptions.ExecuteSynchronously); } } - private static readonly Action CloseContextOnCompleteAction = (t, s) => CloseContextOnComplete(t, s); - private static void CloseContextOnComplete(Task t, object c) => _ = ((IChannelHandlerContext)c).CloseAsync(); + private static readonly Action CloseContextOnCompleteAction = (t, s) => CloseContextOnComplete(s); + private static void CloseContextOnComplete(object c) => _ = ((IChannelHandlerContext)c).CloseAsync(); [MethodImpl(InlineMethod.AggressiveOptimization)] @@ -98,8 +98,8 @@ public static Task CloseOnComplete(this Task task, IChannelHandlerContext ctx, I return task.ContinueWith(CloseWrappedContextOnCompleteAction, (ctx, promise), TaskContinuationOptions.ExecuteSynchronously); } } - private static readonly Action CloseWrappedContextOnCompleteAction = (t, s) => CloseWrappedContextOnComplete(t, s); - private static void CloseWrappedContextOnComplete(Task t, object s) + private static readonly Action CloseWrappedContextOnCompleteAction = (t, s) => CloseWrappedContextOnComplete(s); + private static void CloseWrappedContextOnComplete(object s) { var wrapped = ((IChannelHandlerContext, IPromise))s; _ = wrapped.Item1.CloseAsync(wrapped.Item2); diff --git a/src/DotNetty.Transport/DotNetty.Transport.csproj b/src/DotNetty.Transport/DotNetty.Transport.csproj index 53930c1ee..f9e0c6d92 100644 --- a/src/DotNetty.Transport/DotNetty.Transport.csproj +++ b/src/DotNetty.Transport/DotNetty.Transport.csproj @@ -19,7 +19,6 @@ - diff --git a/test/DotNetty.Codecs.Http2.Tests.Netstandard/DotNetty.Codecs.Http2.Tests.csproj b/test/DotNetty.Codecs.Http2.Tests.Netstandard/DotNetty.Codecs.Http2.Tests.csproj index 4980e0377..624230b4a 100644 --- a/test/DotNetty.Codecs.Http2.Tests.Netstandard/DotNetty.Codecs.Http2.Tests.csproj +++ b/test/DotNetty.Codecs.Http2.Tests.Netstandard/DotNetty.Codecs.Http2.Tests.csproj @@ -20,7 +20,6 @@ - diff --git a/test/DotNetty.Codecs.Http2.Tests/DataCompressionHttp2Test.cs b/test/DotNetty.Codecs.Http2.Tests/DataCompressionHttp2Test.cs index 01874fe6a..774f89180 100644 --- a/test/DotNetty.Codecs.Http2.Tests/DataCompressionHttp2Test.cs +++ b/test/DotNetty.Codecs.Http2.Tests/DataCompressionHttp2Test.cs @@ -18,7 +18,7 @@ namespace DotNetty.Codecs.Http2.Tests using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; - using DotNetty.Transport.Libuv; + //using DotNetty.Transport.Libuv; using Moq; using Xunit; using Xunit.Abstractions; @@ -40,29 +40,29 @@ namespace DotNetty.Codecs.Http2.Tests // } //} - public class LibuvDataCompressionHttp2Test : AbstractDataCompressionHttp2Test - { - static LibuvDataCompressionHttp2Test() - { - DotNetty.Common.ResourceLeakDetector.Level = Common.ResourceLeakDetector.DetectionLevel.Disabled; - } + //public class LibuvDataCompressionHttp2Test : AbstractDataCompressionHttp2Test + //{ + // static LibuvDataCompressionHttp2Test() + // { + // DotNetty.Common.ResourceLeakDetector.Level = Common.ResourceLeakDetector.DetectionLevel.Disabled; + // } - public LibuvDataCompressionHttp2Test(ITestOutputHelper output) : base(output) { } + // public LibuvDataCompressionHttp2Test(ITestOutputHelper output) : base(output) { } - protected override void SetupServerBootstrap(ServerBootstrap bootstrap) - { - var dispatcher = new DispatcherEventLoopGroup(); - var bossGroup = dispatcher; - var workGroup = new WorkerEventLoopGroup(dispatcher); - bootstrap.Group(bossGroup, workGroup) - .Channel(); - } + // protected override void SetupServerBootstrap(ServerBootstrap bootstrap) + // { + // var dispatcher = new DispatcherEventLoopGroup(); + // var bossGroup = dispatcher; + // var workGroup = new WorkerEventLoopGroup(dispatcher); + // bootstrap.Group(bossGroup, workGroup) + // .Channel(); + // } - protected override void SetupBootstrap(Bootstrap bootstrap) - { - bootstrap.Group(new EventLoopGroup()).Channel(); - } - } + // protected override void SetupBootstrap(Bootstrap bootstrap) + // { + // bootstrap.Group(new EventLoopGroup()).Channel(); + // } + //} //public sealed class TlsSocketDataCompressionHttp2Test : SocketDataCompressionHttp2Test //{ diff --git a/test/DotNetty.Codecs.Http2.Tests/DotNetty.Codecs.Http2.Tests.csproj b/test/DotNetty.Codecs.Http2.Tests/DotNetty.Codecs.Http2.Tests.csproj index 12241e400..7aa89465e 100644 --- a/test/DotNetty.Codecs.Http2.Tests/DotNetty.Codecs.Http2.Tests.csproj +++ b/test/DotNetty.Codecs.Http2.Tests/DotNetty.Codecs.Http2.Tests.csproj @@ -23,7 +23,6 @@ - diff --git a/test/DotNetty.Codecs.Http2.Tests/Http2ConnectionRoundtripTest.cs b/test/DotNetty.Codecs.Http2.Tests/Http2ConnectionRoundtripTest.cs index a3a82c043..250a6a936 100644 --- a/test/DotNetty.Codecs.Http2.Tests/Http2ConnectionRoundtripTest.cs +++ b/test/DotNetty.Codecs.Http2.Tests/Http2ConnectionRoundtripTest.cs @@ -17,44 +17,44 @@ namespace DotNetty.Codecs.Http2.Tests using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Local; using DotNetty.Transport.Channels.Sockets; - using DotNetty.Transport.Libuv; + //using DotNetty.Transport.Libuv; using Moq; using Xunit; using Xunit.Abstractions; - public sealed class LibuvHttp2ConnectionRoundtripTest : AbstractHttp2ConnectionRoundtripTest - { - static LibuvHttp2ConnectionRoundtripTest() - { - DotNetty.Common.ResourceLeakDetector.Level = Common.ResourceLeakDetector.DetectionLevel.Disabled; - } + //public sealed class LibuvHttp2ConnectionRoundtripTest : AbstractHttp2ConnectionRoundtripTest + //{ + // static LibuvHttp2ConnectionRoundtripTest() + // { + // DotNetty.Common.ResourceLeakDetector.Level = Common.ResourceLeakDetector.DetectionLevel.Disabled; + // } - public LibuvHttp2ConnectionRoundtripTest(ITestOutputHelper output) : base(output) { } + // public LibuvHttp2ConnectionRoundtripTest(ITestOutputHelper output) : base(output) { } - protected override void SetupServerBootstrap(ServerBootstrap bootstrap) - { - var dispatcher = new DispatcherEventLoopGroup(); - var bossGroup = dispatcher; - var workGroup = new WorkerEventLoopGroup(dispatcher); - bootstrap.Group(bossGroup, workGroup) - .Channel(); - } + // protected override void SetupServerBootstrap(ServerBootstrap bootstrap) + // { + // var dispatcher = new DispatcherEventLoopGroup(); + // var bossGroup = dispatcher; + // var workGroup = new WorkerEventLoopGroup(dispatcher); + // bootstrap.Group(bossGroup, workGroup) + // .Channel(); + // } - protected override void SetupBootstrap(Bootstrap bootstrap) - { - bootstrap.Group(new EventLoopGroup()).Channel(); - } + // protected override void SetupBootstrap(Bootstrap bootstrap) + // { + // bootstrap.Group(new EventLoopGroup()).Channel(); + // } - [Fact(Skip = "not yet supported")] - public override void FlowControlProperlyChunksLargeMessage() - { - } + // [Fact(Skip = "not yet supported")] + // public override void FlowControlProperlyChunksLargeMessage() + // { + // } - [Fact(Skip = "not yet supported")] - public override void StressTest() - { - } - } + // [Fact(Skip = "not yet supported")] + // public override void StressTest() + // { + // } + //} //public sealed class SocketHttp2ConnectionRoundtripTest : AbstractHttp2ConnectionRoundtripTest //{ diff --git a/test/DotNetty.Codecs.Http2.Tests/HttpToHttp2ConnectionHandlerTest.cs b/test/DotNetty.Codecs.Http2.Tests/HttpToHttp2ConnectionHandlerTest.cs index 0fb0ea907..b0282cb0a 100644 --- a/test/DotNetty.Codecs.Http2.Tests/HttpToHttp2ConnectionHandlerTest.cs +++ b/test/DotNetty.Codecs.Http2.Tests/HttpToHttp2ConnectionHandlerTest.cs @@ -19,35 +19,35 @@ namespace DotNetty.Codecs.Http2.Tests using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Local; using DotNetty.Transport.Channels.Sockets; - using DotNetty.Transport.Libuv; + //using DotNetty.Transport.Libuv; using Moq; using Xunit; using Xunit.Abstractions; - public sealed class LibuvHttpToHttp2ConnectionHandlerTest : AbstractHttpToHttp2ConnectionHandlerTest - { - static LibuvHttpToHttp2ConnectionHandlerTest() - { - DotNetty.Common.ResourceLeakDetector.Level = Common.ResourceLeakDetector.DetectionLevel.Disabled; - } + //public sealed class LibuvHttpToHttp2ConnectionHandlerTest : AbstractHttpToHttp2ConnectionHandlerTest + //{ + // static LibuvHttpToHttp2ConnectionHandlerTest() + // { + // DotNetty.Common.ResourceLeakDetector.Level = Common.ResourceLeakDetector.DetectionLevel.Disabled; + // } - public LibuvHttpToHttp2ConnectionHandlerTest(ITestOutputHelper output) : base(output) { } + // public LibuvHttpToHttp2ConnectionHandlerTest(ITestOutputHelper output) : base(output) { } - protected override void SetupServerBootstrap(ServerBootstrap bootstrap) - { - var dispatcher = new DispatcherEventLoopGroup(); - var bossGroup = dispatcher; - var workGroup = new WorkerEventLoopGroup(dispatcher); - bootstrap.Group(bossGroup, workGroup) - .Channel(); - //bootstrap.Handler(new DotNetty.Handlers.Logging.LoggingHandler("LSTN")); - } + // protected override void SetupServerBootstrap(ServerBootstrap bootstrap) + // { + // var dispatcher = new DispatcherEventLoopGroup(); + // var bossGroup = dispatcher; + // var workGroup = new WorkerEventLoopGroup(dispatcher); + // bootstrap.Group(bossGroup, workGroup) + // .Channel(); + // //bootstrap.Handler(new DotNetty.Handlers.Logging.LoggingHandler("LSTN")); + // } - protected override void SetupBootstrap(Bootstrap bootstrap) - { - bootstrap.Group(new EventLoopGroup()).Channel(); - } - } + // protected override void SetupBootstrap(Bootstrap bootstrap) + // { + // bootstrap.Group(new EventLoopGroup()).Channel(); + // } + //} //public sealed class SocketHttpToHttp2ConnectionHandlerTest : AbstractHttpToHttp2ConnectionHandlerTest //{ diff --git a/test/DotNetty.Codecs.Http2.Tests/InboundHttp2ToHttpAdapterTest.cs b/test/DotNetty.Codecs.Http2.Tests/InboundHttp2ToHttpAdapterTest.cs index 1bad027cd..b04f9e5b5 100644 --- a/test/DotNetty.Codecs.Http2.Tests/InboundHttp2ToHttpAdapterTest.cs +++ b/test/DotNetty.Codecs.Http2.Tests/InboundHttp2ToHttpAdapterTest.cs @@ -19,34 +19,34 @@ namespace DotNetty.Codecs.Http2.Tests using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Local; using DotNetty.Transport.Channels.Sockets; - using DotNetty.Transport.Libuv; + //using DotNetty.Transport.Libuv; using Moq; using Xunit; using Xunit.Abstractions; - public sealed class LibuvInboundHttp2ToHttpAdapterTest : AbstractInboundHttp2ToHttpAdapterTest - { - static LibuvInboundHttp2ToHttpAdapterTest() - { - DotNetty.Common.ResourceLeakDetector.Level = Common.ResourceLeakDetector.DetectionLevel.Disabled; - } + //public sealed class LibuvInboundHttp2ToHttpAdapterTest : AbstractInboundHttp2ToHttpAdapterTest + //{ + // static LibuvInboundHttp2ToHttpAdapterTest() + // { + // DotNetty.Common.ResourceLeakDetector.Level = Common.ResourceLeakDetector.DetectionLevel.Disabled; + // } - public LibuvInboundHttp2ToHttpAdapterTest(ITestOutputHelper output) : base(output) { } + // public LibuvInboundHttp2ToHttpAdapterTest(ITestOutputHelper output) : base(output) { } - protected override void SetupServerBootstrap(ServerBootstrap bootstrap) - { - var dispatcher = new DispatcherEventLoopGroup(); - var bossGroup = dispatcher; - var workGroup = new WorkerEventLoopGroup(dispatcher); - bootstrap.Group(bossGroup, workGroup) - .Channel(); - } + // protected override void SetupServerBootstrap(ServerBootstrap bootstrap) + // { + // var dispatcher = new DispatcherEventLoopGroup(); + // var bossGroup = dispatcher; + // var workGroup = new WorkerEventLoopGroup(dispatcher); + // bootstrap.Group(bossGroup, workGroup) + // .Channel(); + // } - protected override void SetupBootstrap(Bootstrap bootstrap) - { - bootstrap.Group(new EventLoopGroup()).Channel(); - } - } + // protected override void SetupBootstrap(Bootstrap bootstrap) + // { + // bootstrap.Group(new EventLoopGroup()).Channel(); + // } + //} //public sealed class TlsSocketInboundHttp2ToHttpAdapterTest : SocketInboundHttp2ToHttpAdapterTest //{ diff --git a/test/DotNetty.NetUV.Tests.Netstandard/DotNetty.NetUV.Tests.csproj b/test/DotNetty.NetUV.Tests.Netstandard/DotNetty.NetUV.Tests.csproj deleted file mode 100644 index 551539f1e..000000000 --- a/test/DotNetty.NetUV.Tests.Netstandard/DotNetty.NetUV.Tests.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - - netcoreapp3.1;netcoreapp2.1 - DotNetty.NetUV.Tests - DotNetty.NetUV.Tests - false - - - - - - - - - - - - - - - - - - - - diff --git a/test/DotNetty.NetUV.Tests.Netstandard/run.netcore21.cmd b/test/DotNetty.NetUV.Tests.Netstandard/run.netcore21.cmd deleted file mode 100644 index d492db3f0..000000000 --- a/test/DotNetty.NetUV.Tests.Netstandard/run.netcore21.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet test --framework netcoreapp2.1 -- RunConfiguration.TargetPlatform=x64 \ No newline at end of file diff --git a/test/DotNetty.NetUV.Tests.Netstandard/run.netcore31.cmd b/test/DotNetty.NetUV.Tests.Netstandard/run.netcore31.cmd deleted file mode 100644 index dd3df93ee..000000000 --- a/test/DotNetty.NetUV.Tests.Netstandard/run.netcore31.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet test --framework netcoreapp3.1 -- RunConfiguration.TargetPlatform=x64 \ No newline at end of file diff --git a/test/DotNetty.NetUV.Tests/DotNetty.NetUV.Tests.csproj b/test/DotNetty.NetUV.Tests/DotNetty.NetUV.Tests.csproj deleted file mode 100644 index aac3b4473..000000000 --- a/test/DotNetty.NetUV.Tests/DotNetty.NetUV.Tests.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - - $(StandardTestTfms) - DotNetty.NetUV.Tests - DotNetty.NetUV.Tests - false - - - win-x64 - - - - - - - - - - - - - - diff --git a/test/DotNetty.NetUV.Tests/run.net452.cmd b/test/DotNetty.NetUV.Tests/run.net452.cmd deleted file mode 100644 index ebe78ae0d..000000000 --- a/test/DotNetty.NetUV.Tests/run.net452.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet test --framework net452 -- RunConfiguration.TargetPlatform=x64 \ No newline at end of file diff --git a/test/DotNetty.NetUV.Tests/run.net471.cmd b/test/DotNetty.NetUV.Tests/run.net471.cmd deleted file mode 100644 index 681100617..000000000 --- a/test/DotNetty.NetUV.Tests/run.net471.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet test --framework net471 -- RunConfiguration.TargetPlatform=x64 \ No newline at end of file diff --git a/test/DotNetty.NetUV.Tests/run.net5.cmd b/test/DotNetty.NetUV.Tests/run.net5.cmd deleted file mode 100644 index c4f8ec361..000000000 --- a/test/DotNetty.NetUV.Tests/run.net5.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet test --framework net5.0 -- RunConfiguration.TargetPlatform=x64 \ No newline at end of file diff --git a/test/DotNetty.NetUV.Tests/run.netcore21.cmd b/test/DotNetty.NetUV.Tests/run.netcore21.cmd deleted file mode 100644 index d492db3f0..000000000 --- a/test/DotNetty.NetUV.Tests/run.netcore21.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet test --framework netcoreapp2.1 -- RunConfiguration.TargetPlatform=x64 \ No newline at end of file diff --git a/test/DotNetty.NetUV.Tests/run.netcore31.cmd b/test/DotNetty.NetUV.Tests/run.netcore31.cmd deleted file mode 100644 index dd3df93ee..000000000 --- a/test/DotNetty.NetUV.Tests/run.netcore31.cmd +++ /dev/null @@ -1 +0,0 @@ -dotnet test --framework netcoreapp3.1 -- RunConfiguration.TargetPlatform=x64 \ No newline at end of file diff --git a/test/DotNetty.Transport.Libuv.Tests/AutoReadTests.cs b/test/DotNetty.Transport.Libuv.Tests/AutoReadTests.cs deleted file mode 100644 index 1307cd96b..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/AutoReadTests.cs +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - using DotNetty.Buffers; - using DotNetty.Common.Utilities; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class AutoReadTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public AutoReadTests() - { - this.group = new EventLoopGroup(1); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void AutoReadOffDuringReadOnlyReadsOneTime(bool readOutsideEventLoopThread) - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel(); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.AutoReadOffDuringReadOnlyReadsOneTime0(readOutsideEventLoopThread, sb, cb); - } - - void AutoReadOffDuringReadOnlyReadsOneTime0(bool readOutsideEventLoopThread, ServerBootstrap sb, Bootstrap cb) - { - var serverInitializer = new AutoReadInitializer(!readOutsideEventLoopThread); - var clientInitializer = new AutoReadInitializer(!readOutsideEventLoopThread); - sb.Option(ChannelOption.SoBacklog, 1024) - .Option(ChannelOption.AutoRead, true) - .ChildOption(ChannelOption.AutoRead, true) - // We want to ensure that we attempt multiple individual read operations per read loop so we can - // test the auto read feature being turned off when data is first read. - .ChildOption(ChannelOption.RcvbufAllocator, new TestRecvByteBufAllocator()) - .ChildHandler(serverInitializer); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - cb.Option(ChannelOption.AutoRead, true) - // We want to ensure that we attempt multiple individual read operations per read loop so we can - // test the auto read feature being turned off when data is first read. - .Option(ChannelOption.RcvbufAllocator, new TestRecvByteBufAllocator()) - .Handler(clientInitializer); - - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - // 3 bytes means 3 independent reads for TestRecvByteBufAllocator - Task writeTask = this.clientChannel.WriteAndFlushAsync(Unpooled.WrappedBuffer(new byte[3])); - Assert.True(writeTask.Wait(TimeSpan.FromSeconds(5)), "Client write task timed out"); - serverInitializer.AutoReadHandler.AssertSingleRead(); - - // 3 bytes means 3 independent reads for TestRecvByteBufAllocator - writeTask = serverInitializer.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(new byte[3])); - Assert.True(writeTask.Wait(TimeSpan.FromSeconds(5)), "Server write task timed out"); - clientInitializer.AutoReadHandler.AssertSingleRead(); - - if (readOutsideEventLoopThread) - { - serverInitializer.Channel.Read(); - } - serverInitializer.AutoReadHandler.AssertSingleReadSecondTry(); - - if (readOutsideEventLoopThread) - { - this.clientChannel.Read(); - } - clientInitializer.AutoReadHandler.AssertSingleReadSecondTry(); - } - - sealed class AutoReadInitializer : ChannelInitializer - { - internal readonly AutoReadHandler AutoReadHandler; - internal IChannel Channel; - - internal AutoReadInitializer(bool readInEventLoop) - { - this.AutoReadHandler = new AutoReadHandler(readInEventLoop); - } - - protected override void InitChannel(IChannel ch) - { - this.Channel = ch; - ch.Pipeline.AddLast(this.AutoReadHandler); - } - } - - sealed class AutoReadHandler : ChannelHandlerAdapter - { - readonly CountdownEvent latch; - readonly CountdownEvent latch2; - readonly bool callRead; - int count; - - internal AutoReadHandler(bool callRead) - { - this.callRead = callRead; - this.latch = new CountdownEvent(1); - this.latch2 = new CountdownEvent(callRead ? 3 : 2); - } - - public override void ChannelRead(IChannelHandlerContext ctx, object msg) - { - ReferenceCountUtil.Release(msg); - if (Interlocked.Increment(ref this.count) == 1) - { - ctx.Channel.Configuration.IsAutoRead = false; - } - if (this.callRead) - { - ctx.Read(); - } - } - - public override void ChannelReadComplete(IChannelHandlerContext context) - { - if (!this.latch.IsSet) - { - this.latch.Signal(); - } - this.latch2.Signal(); - } - - internal void AssertSingleRead() - { - Assert.True(this.latch.Wait(TimeSpan.FromSeconds(5))); - Assert.True(this.count > 0); - } - - internal void AssertSingleReadSecondTry() - { - Assert.True(this.latch2.Wait(TimeSpan.FromSeconds(5)), $"Expected count down remaining {this.latch2.CurrentCount}"); - Assert.Equal(this.callRead ? 3 : 2, this.count); - } - } - - sealed class TestRecvByteBufAllocator : IRecvByteBufAllocator - { - public IRecvByteBufAllocatorHandle NewHandle() => new Handle(); - - sealed class Handle : IRecvByteBufAllocatorHandle - { - IChannelConfiguration config; - - public IByteBuffer Allocate(IByteBufferAllocator alloc) => alloc.Buffer(this.Guess(), this.Guess()); - - // only ever allocate buffers of size 1 to ensure the number of reads is controlled. - public int Guess() => 1; - - public void Reset(IChannelConfiguration channelConfig) - { - this.config = channelConfig; - } - - public void IncMessagesRead(int numMessages) - { - // No need to track the number of messages read because it is not used. - } - - public int LastBytesRead { get; set; } - - public int AttemptedBytesRead { get; set; } - - public bool ContinueReading() => this.config.IsAutoRead; - - public void ReadComplete() - { - // Nothing needs to be done or adjusted after each read cycle is completed. - } - } - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/BufReleaseTests.cs b/test/DotNetty.Transport.Libuv.Tests/BufReleaseTests.cs deleted file mode 100644 index fb98c2a24..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/BufReleaseTests.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading.Tasks; - using DotNetty.Buffers; - using DotNetty.Common.Concurrency; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class BufReleaseTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public BufReleaseTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void BufRelease() - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel(); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.BufRelease0(sb, cb); - } - - void BufRelease0(ServerBootstrap sb, Bootstrap cb) - { - var serverHandler = new BufWriterHandler(); - var clientHandler = new BufWriterHandler(); - - sb.ChildHandler(serverHandler); - cb.Handler(clientHandler); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - // Ensure the server socket accepted the client connection *and* initialized pipeline successfully. - Assert.True(serverHandler.Added.Wait(DefaultTimeout), "Channel HandlerAdded timed out"); - - // and then close all sockets. - this.serverChannel.CloseAsync().Wait(DefaultTimeout); - this.clientChannel.CloseAsync().Wait(DefaultTimeout); - - serverHandler.Check(); - clientHandler.Check(); - - serverHandler.Release(); - clientHandler.Release(); - } - - sealed class BufWriterHandler : SimpleChannelInboundHandler - { - readonly Random random; - readonly DefaultPromise completion; - - IByteBuffer buf; - Task writeTask; - - public BufWriterHandler() - { - this.random = new Random(); - this.completion = new DefaultPromise(); - } - - public Task Added => this.completion.Task; - - public override void HandlerAdded(IChannelHandlerContext context) - { - this.completion.TryComplete(); - } - - public override void ChannelActive(IChannelHandlerContext ctx) - { - var data = new byte[1024]; - this.random.NextBytes(data); - - this.buf = ctx.Allocator.Buffer(); - // call retain on it so it can't be put back on the pool - this.buf.WriteBytes(data).Retain(); - - this.writeTask = ctx.Channel.WriteAndFlushAsync(this.buf); - } - - protected override void ChannelRead0(IChannelHandlerContext ctx, object msg) - { - // discard - } - - public void Check() - { - Assert.NotNull(this.writeTask); - Assert.True(this.writeTask.Wait(DefaultTimeout), "Write task timed out"); - Assert.Equal(1, this.buf.ReferenceCount); - } - - public void Release() - { - this.buf.Release(); - } - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/CloseForciblyTests.cs b/test/DotNetty.Transport.Libuv.Tests/CloseForciblyTests.cs deleted file mode 100644 index b388bb062..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/CloseForciblyTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading.Tasks; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public class CloseForciblyTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public CloseForciblyTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void CloseForcibly() - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel(); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.CloseForcibly0(sb, cb); - } - - void CloseForcibly0(ServerBootstrap sb, Bootstrap cb) - { - sb.Handler(new InboundHandler()) - .ChildHandler(new ChannelHandlerAdapter()); - cb.Handler(new ChannelHandlerAdapter()); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - this.clientChannel.CloseAsync().Wait(DefaultTimeout); - - this.serverChannel.CloseAsync().Wait(DefaultTimeout); - } - - sealed class InboundHandler : ChannelHandlerAdapter - { - public override void ChannelRead(IChannelHandlerContext context, object message) - { - var childChannel = (TcpChannel)message; - childChannel.Unsafe.CloseForcibly(); - } - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/CompositeBufferGatheringWriteTests.cs b/test/DotNetty.Transport.Libuv.Tests/CompositeBufferGatheringWriteTests.cs deleted file mode 100644 index f21f7efc3..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/CompositeBufferGatheringWriteTests.cs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading.Tasks; - using DotNetty.Buffers; - using DotNetty.Common.Concurrency; - using DotNetty.Common.Utilities; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class CompositeBufferGatheringWriteTests : IDisposable - { - const int ExpectedBytes = 20; - - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public CompositeBufferGatheringWriteTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void SingleCompositeBufferWrite() - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel(); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.SingleCompositeBufferWrite0(sb, cb); - } - - void SingleCompositeBufferWrite0(ServerBootstrap sb, Bootstrap cb) - { - sb.ChildHandler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast(new ServerHandler()); - })); - - var clientHandler = new ClientHandler(); - cb.Handler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast(clientHandler); - })); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - IByteBuffer expected = NewCompositeBuffer(this.clientChannel.Allocator); - clientHandler.AssertReceived(expected); - } - - sealed class ClientHandler : ChannelHandlerAdapter - { - readonly DefaultPromise completion; - - IByteBuffer aggregator; - - public ClientHandler() - { - this.completion = new DefaultPromise(); - } - - public override void HandlerAdded(IChannelHandlerContext ctx) - { - this.aggregator = ctx.Allocator.Buffer(ExpectedBytes); - } - - public override void ChannelRead(IChannelHandlerContext ctx, object msg) - { - try - { - if (msg is IByteBuffer buf) - { - this.aggregator.WriteBytes(buf); - } - } - finally - { - ReferenceCountUtil.Release(msg); - } - } - - public override void ExceptionCaught(IChannelHandlerContext ctx, Exception exception) - { - this.completion.TrySetException(exception); - } - - public override void ChannelInactive(IChannelHandlerContext ctx) - { - this.completion.TryComplete(); - } - - public void AssertReceived(IByteBuffer expected) - { - try - { - Assert.True(this.completion.Task.Wait(DefaultTimeout), "ChannelInactive timed out"); - Assert.NotNull(this.aggregator); - Assert.Equal(ExpectedBytes, this.aggregator.ReadableBytes); - Assert.Equal(expected, this.aggregator); - } - finally - { - expected.Release(); - this.aggregator?.Release(); - } - } - } - - sealed class ServerHandler : ChannelHandlerAdapter - { - public override void ChannelActive(IChannelHandlerContext ctx) => - ctx.WriteAndFlushAsync(NewCompositeBuffer(ctx.Allocator)) - .ContinueWith((t, s) => ((IChannelHandlerContext)s).CloseAsync(), - ctx, TaskContinuationOptions.ExecuteSynchronously); - } - - static IByteBuffer NewCompositeBuffer(IByteBufferAllocator alloc) - { - CompositeByteBuffer compositeByteBuf = alloc.CompositeBuffer(); - compositeByteBuf.AddComponent(true, alloc.DirectBuffer(4).WriteInt(100)); - compositeByteBuf.AddComponent(true, alloc.DirectBuffer(8).WriteLong(123)); - compositeByteBuf.AddComponent(true, alloc.DirectBuffer(8).WriteLong(456)); - Assert.Equal(ExpectedBytes, compositeByteBuf.ReadableBytes); - return compositeByteBuf; - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/ConnectTests.cs b/test/DotNetty.Transport.Libuv.Tests/ConnectTests.cs deleted file mode 100644 index 9ad3bd269..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/ConnectTests.cs +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading.Tasks; - using DotNetty.Handlers.Logging; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using DotNetty.Transport.Libuv.Native; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class ConnectTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public ConnectTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void Connect() - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel() - .ChildHandler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast("server logger", new LoggingHandler($"{nameof(ConnectTests)}")); - })); - - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel() - .Handler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast("client logger", new LoggingHandler($"{nameof(ConnectTests)}")); - })); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - } - - [Fact] - public void MultipleConnect() - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel() - .ChildHandler(new ChannelHandlerAdapter()); - - var address = new IPEndPoint(IPAddress.IPv6Loopback, 0); - // start server - Task task = sb.BindAsync(address); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel() - .Handler(new ChannelHandlerAdapter()); - - // connect to server - task = (Task)cb.RegisterAsync(); - Assert.True(task.Wait(DefaultTimeout)); - this.clientChannel = task.Result; - Task connectTask = this.clientChannel.ConnectAsync(endPoint); - Assert.True(connectTask.Wait(DefaultTimeout), "Connect to server timed out"); - - if (PlatformApi.IsWindows) // TODO Ubuntu 无异常 - { - // Attempt to connect again - connectTask = this.clientChannel.ConnectAsync(endPoint); - var exception = Assert.Throws(() => connectTask.Wait(DefaultTimeout)); - Assert.IsType(exception.InnerExceptions[0]); - var operationException = (OperationException)exception.InnerExceptions[0]; - Assert.Equal("EISCONN", operationException.Name); // socket is already connected - } - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/ConnectionAttemptTests.cs b/test/DotNetty.Transport.Libuv.Tests/ConnectionAttemptTests.cs deleted file mode 100644 index fb1f1517b..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/ConnectionAttemptTests.cs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading.Tasks; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using DotNetty.Transport.Libuv.Native; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class ConnectionAttemptTests : IDisposable - { - // See /etc/services - const int UnassignedPort = 4; - - readonly IEventLoopGroup group; - - public ConnectionAttemptTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void ConnectTimeout() - { - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - ConnectTimeout0(cb); - } - - static void ConnectTimeout0(Bootstrap cb) - { - var handler = new TestHandler(); - cb.Handler(handler) - .Option(ChannelOption.ConnectTimeout, TimeSpan.FromSeconds(2)); - - IPAddress ipAddress = IPAddress.Parse("198.51.100.254"); - var badAddress = new IPEndPoint(ipAddress, 65535); - Task task = cb.ConnectAsync(badAddress); - var error = Assert.Throws(() => task.Wait(DefaultTimeout)); - - Assert.Single(error.InnerExceptions); - Assert.IsType(error.InnerException); - Assert.Equal(0, handler.Active); - Assert.Null(handler.Error); - } - - [Fact] - public void ConnectRefused() - { - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - ConnectRefused0(cb); - } - - static void ConnectRefused0(Bootstrap cb) - { - var handler = new TestHandler(); - cb.Handler(handler); - var badAddress = new IPEndPoint(IPAddress.Loopback, UnassignedPort); - Task task = cb.ConnectAsync(badAddress); - var error = Assert.Throws(() => task.Wait(DefaultTimeout)); - - Assert.Single(error.InnerExceptions); - Assert.IsType(error.InnerException); - var exception = (ChannelException)error.InnerException; - Assert.IsType(exception.InnerException); - var operationException = (OperationException)exception.InnerException; - Assert.Equal(ErrorCode.ECONNREFUSED, operationException.ErrorCode); - Assert.Equal(0, handler.Active); - Assert.Null(handler.Error); - } - - sealed class TestHandler : ChannelHandlerAdapter - { - public Exception Error { get; private set; } - - public int Active { get; private set; } - - public override void ChannelActive(IChannelHandlerContext context) - { - this.Active++; - } - - public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) - { - this.Error = exception; - } - } - - public void Dispose() - { - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/DetectPeerCloseWithoutReadTests.cs b/test/DotNetty.Transport.Libuv.Tests/DetectPeerCloseWithoutReadTests.cs deleted file mode 100644 index 838c48cfa..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/DetectPeerCloseWithoutReadTests.cs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - using DotNetty.Buffers; - using DotNetty.Common.Concurrency; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class DetectPeerCloseWithoutReadTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public DetectPeerCloseWithoutReadTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void ClientCloseWithoutServerReadIsDetected() - { - const int ExpectedBytes = 100; - - var serverHandler = new TestHandler(ExpectedBytes); - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel() - .ChildOption(ChannelOption.AutoRead, false) - .ChildHandler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast(serverHandler); - })); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - // connect to server - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel() - .Handler(new ChannelHandlerAdapter()); - - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - IByteBuffer buf = this.clientChannel.Allocator.Buffer(ExpectedBytes); - buf.SetWriterIndex(buf.WriterIndex + ExpectedBytes); - this.clientChannel.WriteAndFlushAsync(buf).ContinueWith(_ => this.clientChannel.CloseAsync()); - - Task completion = serverHandler.Completion; - Assert.True(completion.Wait(DefaultTimeout)); - Assert.Equal(ExpectedBytes, completion.Result); - } - - sealed class TestHandler : SimpleChannelInboundHandler - { - readonly int expectedBytesRead; - readonly TaskCompletionSource completion; - int bytesRead; - - public TestHandler(int expectedBytesRead) - { - this.expectedBytesRead = expectedBytesRead; - this.completion = new TaskCompletionSource(); - } - - public Task Completion => this.completion.Task; - - public override void ChannelActive(IChannelHandlerContext ctx) - { - if (!ctx.Channel.Configuration.IsAutoRead) - { - ctx.Read(); - } - } - - protected override void ChannelRead0(IChannelHandlerContext ctx, IByteBuffer msg) - { - if (Interlocked.Add(ref this.bytesRead, msg.ReadableBytes) >= this.expectedBytesRead) - { - this.completion.TrySetResult(this.bytesRead); - } - // Because autoread is off, we call read to consume all data until we detect the close. - ctx.Read(); - } - - public override void ChannelInactive(IChannelHandlerContext ctx) - { - this.completion.TrySetResult(this.bytesRead); - ctx.FireChannelInactive(); - } - } - - [Fact] - public void ServerCloseWithoutClientReadIsDetected() - { - const int ExpectedBytes = 100; - - var serverHandler = new WriteHandler(ExpectedBytes); - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel() - .ChildHandler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast(serverHandler); - })); - - var address = new IPEndPoint(IPAddress.IPv6Loopback, 0); - // start server - // start server - Task task = sb.BindAsync(address); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - // connect to server - var clientHandler = new TestHandler(ExpectedBytes); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel() - .Option(ChannelOption.AutoRead, false) - .Handler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast(clientHandler); - })); - - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - // Wait until server inactive to read on client - Assert.True(serverHandler.Inactive.Wait(DefaultTimeout)); - this.clientChannel.Read(); - Task completion = clientHandler.Completion; - Assert.True(completion.Wait(DefaultTimeout)); - Assert.Equal(ExpectedBytes, completion.Result); - } - - sealed class WriteHandler : ChannelHandlerAdapter - { - readonly int expectedBytesRead; - readonly DefaultPromise completion; - - public WriteHandler(int expectedBytesRead) - { - this.expectedBytesRead = expectedBytesRead; - this.completion = new DefaultPromise(); - } - - public Task Inactive => this.completion.Task; - - public override void ChannelActive(IChannelHandlerContext ctx) - { - IByteBuffer buf = ctx.Allocator.Buffer(this.expectedBytesRead); - buf.SetWriterIndex(buf.WriterIndex + this.expectedBytesRead); - ctx.WriteAndFlushAsync(buf).ContinueWith(_ => ctx.CloseAsync()); - ctx.FireChannelActive(); - } - - public override void ChannelInactive(IChannelHandlerContext context) => this.completion.TryComplete(); - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/EchoTests.cs b/test/DotNetty.Transport.Libuv.Tests/EchoTests.cs deleted file mode 100644 index dd82a839c..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/EchoTests.cs +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading.Tasks; - using DotNetty.Buffers; - using DotNetty.Common.Concurrency; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - using Xunit.Abstractions; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class EchoTests : IDisposable - { - readonly ITestOutputHelper output; - readonly Random random = new Random(); - readonly byte[] data = new byte[1048576]; - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public EchoTests(ITestOutputHelper output) - { - this.output = output; - this.group = new EventLoopGroup(1); - this.random.NextBytes(this.data); - } - - [Fact] - public void SimpleEcho() => this.Run(false, true); - - [Fact] - public void SimpleEchoNotAutoRead() => this.Run(false, false); - - [Fact] - public void SimpleEchoWithAdditionalExecutor() => this.Run(true, true); - - [Fact] - public void SimpleEchoWithAdditionalExecutorNotAutoRead() => this.Run(true, false); - - void Run(bool additionalExecutor, bool autoRead) - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel(); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.SimpleEcho0(sb, cb, additionalExecutor, autoRead); - } - - void SimpleEcho0(ServerBootstrap sb, Bootstrap cb, bool additionalExecutor, bool autoRead) - { - var sh = new EchoHandler(autoRead, this.data, this.output); - var ch = new EchoHandler(autoRead, this.data, this.output); - - if (additionalExecutor) - { - sb.ChildHandler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast(this.group, sh); - })); - cb.Handler(new ActionChannelInitializer(channel => - { - channel.Pipeline.AddLast(this.group, ch); - })); - } - else - { - sb.ChildHandler(sh); - sb.Handler(new ErrorOutputHandler(this.output)); - cb.Handler(ch); - } - sb.ChildOption(ChannelOption.AutoRead, autoRead); - cb.Option(ChannelOption.AutoRead, autoRead); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - for (int i = 0; i < this.data.Length;) - { - int length = Math.Min(this.random.Next(1024 * 64), this.data.Length - i); - IByteBuffer buf = Unpooled.WrappedBuffer(this.data, i, length); - this.clientChannel.WriteAndFlushAsync(buf); - i += length; - } - - Assert.True(Task.WhenAll(ch.Completion, sh.Completion).Wait(DefaultTimeout), "Echo read/write timed out"); - } - - sealed class ErrorOutputHandler : ChannelHandlerAdapter - { - readonly ITestOutputHelper output; - - public ErrorOutputHandler(ITestOutputHelper output) - { - this.output = output; - } - - public override void ExceptionCaught(IChannelHandlerContext ctx, Exception cause) => this.output.WriteLine(cause.StackTrace); - } - - sealed class EchoHandler : SimpleChannelInboundHandler - { - readonly bool autoRead; - readonly byte[] expected; - readonly ITestOutputHelper output; - readonly DefaultPromise completion; - - IChannel channel; - int counter; - - public EchoHandler(bool autoRead, byte[] expected, ITestOutputHelper output) - { - this.autoRead = autoRead; - this.expected = expected; - this.output = output; - this.completion = new DefaultPromise(); - } - - public override void ChannelActive(IChannelHandlerContext ctx) - { - this.channel = ctx.Channel; - if (!this.autoRead) - { - ctx.Read(); - } - } - - public Task Completion => this.completion.Task; - - protected override void ChannelRead0(IChannelHandlerContext ctx, IByteBuffer msg) - { - var actual = new byte[msg.ReadableBytes]; - msg.ReadBytes(actual); - int lastIdx = this.counter; - - Assert.True(lastIdx + actual.Length <= this.expected.Length); - for (int i = 0; i < actual.Length; i++) - { - Assert.Equal(this.expected[i + lastIdx], actual[i]); - } - - if (this.channel.Parent != null) - { - this.channel.WriteAsync(Unpooled.WrappedBuffer(actual)); - } - - this.counter += actual.Length; - if (this.counter == this.expected.Length) - { - this.completion.TryComplete(); - } - } - - public override void ChannelReadComplete(IChannelHandlerContext ctx) - { - try - { - ctx.Flush(); - } - finally - { - if (!this.autoRead) - { - ctx.Read(); - } - } - } - - public override void ExceptionCaught(IChannelHandlerContext ctx, Exception cause) - { - this.output.WriteLine(cause.StackTrace); - ctx.CloseAsync(); - this.completion.TrySetException(cause); - } - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/EventLoopTests.cs b/test/DotNetty.Transport.Libuv.Tests/EventLoopTests.cs deleted file mode 100644 index 6c8f8e40e..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/EventLoopTests.cs +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using DotNetty.Common; - using DotNetty.Common.Concurrency; - using DotNetty.Tests.Common; - using Xunit; - using Xunit.Abstractions; - using static TestUtil; - - public sealed class EventLoopTests : TestBase, IDisposable - { - readonly EventLoop eventLoop; - readonly NoOp noOp; - - sealed class NoOp : IRunnable - { - public void Run() { } - } - - sealed class RunCounter : IRunnable - { - readonly int expected; - readonly DefaultPromise completionSource; - int count; - - public RunCounter(int expected) - { - this.expected = expected; - this.completionSource = new DefaultPromise(); - } - - public Task Completion => this.completionSource.Task; - - public int Count => this.count; - - public long EndTime { get; private set; } - - public void Run() - { - if (Interlocked.Increment(ref this.count) >= this.expected) - { - this.EndTime = DateTime.UtcNow.Ticks; - this.completionSource.TryComplete(); - } - } - } - - public EventLoopTests(ITestOutputHelper output) : base(output) - { - this.eventLoop = new EventLoop(null); - this.noOp = new NoOp(); - } - - [Fact] - public void Shutdown() - { - Assert.True(this.eventLoop.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout)); - Assert.True(this.eventLoop.IsTerminated); - Assert.Throws(() => this.eventLoop.Execute(this.noOp)); - } - - [Fact] - public void ShutdownAfterExecute() - { - var counter = new RunCounter(1); - this.eventLoop.Execute(counter); - - Assert.True(counter.Completion.Wait(DefaultTimeout)); - Assert.Equal(1, counter.Count); - - Assert.True(this.eventLoop.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout)); - Assert.True(this.eventLoop.IsTerminated); - Assert.Throws(() => this.eventLoop.Execute(this.noOp)); - } - - [Fact] - public void ScheduleTask() - { - const int Delay = 500; - var counter = new RunCounter(1); - long startTime = DateTime.UtcNow.Ticks; - IScheduledTask task = this.eventLoop.Schedule(counter, TimeSpan.FromMilliseconds(Delay)); - Assert.True(task.Completion.Wait(DefaultTimeout)); - Assert.Equal(1, counter.Count); - long delay = counter.EndTime - startTime; - Assert.True(delay > 0); - TimeSpan duration = TimeSpan.FromTicks(delay); - Assert.True(duration.TotalMilliseconds >= Delay, $"Expected delay : {Delay} milliseconds, but was : {duration.TotalMilliseconds}"); - } - - [Fact] - public void RegistrationAfterShutdown() - { - Assert.True(this.eventLoop.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout)); - Assert.True(this.eventLoop.IsTerminated); - - var channel = new TcpChannel(); - var exception = Assert.Throws(() => this.eventLoop.RegisterAsync(channel).Wait(DefaultTimeout)); - Assert.IsType(exception.InnerException); - Assert.False(channel.IsOpen); - } - - [Fact] - public void GracefulShutdownQuietPeriod() - { - Task task = this.eventLoop.ShutdownGracefullyAsync(TimeSpan.FromSeconds(1), TimeSpan.MaxValue); - // Keep Scheduling tasks for another 2 seconds. - for (int i = 0; i < 20; i++) - { - Thread.Sleep(100); - this.eventLoop.Execute(new NoOp()); - } - - long startTime = PreciseTime.NanoTime(); - - Assert.True(this.eventLoop.IsShuttingDown); - Assert.False(this.eventLoop.IsShutdown); - Assert.True(task.Wait(DefaultTimeout), "Loop shutdown timed out"); - - Assert.True(this.eventLoop.IsShuttingDown); - Assert.True(this.eventLoop.IsShutdown); - - long duration = (long)PreciseTime.ToTimeSpan(PreciseTime.NanoTime() - startTime).TotalMilliseconds; - Assert.True(duration >= 1000, $"Expecting shutdown quite period >= 1000 milliseconds, but was {duration}"); - } - - [Fact] - public void GracefulShutdownTimeout() - { - Task task = this.eventLoop.ShutdownGracefullyAsync(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2)); - // Keep Scheduling tasks for another 3 seconds. - // Submitted tasks must be rejected after 2 second timeout. - for (int i = 0; i < 10; i++) - { - Thread.Sleep(100); - this.eventLoop.Execute(new NoOp()); - } - - bool rejected; - try - { - for (int i = 0; i < 20; i++) - { - Thread.Sleep(100); - this.eventLoop.Execute(new NoOp()); - } - rejected = false; - } - catch (RejectedExecutionException) - { - // Expected - rejected = true; - } - - Assert.True(rejected, "Submitted tasks must be rejected after 2 second timeout"); - Assert.True(this.eventLoop.IsShuttingDown); - Assert.True(this.eventLoop.IsShutdown); - Assert.True(task.Wait(DefaultTimeout), "Loop shutdown timed out"); - } - - public void Dispose() - { - this.eventLoop.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/ExceptionHandlingTests.cs b/test/DotNetty.Transport.Libuv.Tests/ExceptionHandlingTests.cs deleted file mode 100644 index 03f5912f0..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/ExceptionHandlingTests.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - using DotNetty.Buffers; - using DotNetty.Common.Concurrency; - using DotNetty.Common.Utilities; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class ExceptionHandlingTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public ExceptionHandlingTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void ReadPendingIsResetAfterEachRead() - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel(); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.ReadPendingIsResetAfterEachRead0(sb, cb); - } - - void ReadPendingIsResetAfterEachRead0(ServerBootstrap sb, Bootstrap cb) - { - var serverInitializer = new MyInitializer(); - sb.Option(ChannelOption.SoBacklog, 1024); - sb.ChildHandler(serverInitializer); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - cb.Handler(new MyInitializer()); - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - Task writeTask = this.clientChannel.WriteAndFlushAsync(Unpooled.WrappedBuffer(new byte[1024])); - Assert.True(writeTask.Wait(DefaultTimeout), "Write task timed out"); - - ExceptionHandler exceptionHandler = serverInitializer.ErrorHandler; - Assert.True(exceptionHandler.Inactive.Wait(DefaultTimeout), "Handler inactive timed out"); - Assert.Equal(1, exceptionHandler.Count); - } - - sealed class MyInitializer : ChannelInitializer - { - public ExceptionHandler ErrorHandler { get; } = new ExceptionHandler(); - - protected override void InitChannel(IChannel ch) - { - IChannelPipeline pipeline = ch.Pipeline; - - pipeline.AddLast(new BuggyChannelHandler()); - pipeline.AddLast(this.ErrorHandler); - } - } - - sealed class BuggyChannelHandler : ChannelHandlerAdapter - { - public override void ChannelRead(IChannelHandlerContext ctx, object msg) - { - ReferenceCountUtil.Release(msg); - throw new NullReferenceException("I am a bug!"); - } - } - - sealed class ExceptionHandler : ChannelHandlerAdapter - { - readonly DefaultPromise completionSource; - int count; - - public ExceptionHandler() - { - this.completionSource = new DefaultPromise(); - } - - public Task Inactive => this.completionSource.Task; - - public int Count => this.count; - - // We expect to get 1 call to ExceptionCaught - public override void ExceptionCaught(IChannelHandlerContext ctx, Exception exception) - { - Interlocked.Increment(ref this.count); - // This should not throw any exception - ctx.CloseAsync(); - } - - public override void ChannelInactive(IChannelHandlerContext context) - { - this.completionSource.TryComplete(); - } - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.NetUV.Tests/Handles/ActiveTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/ActiveTests.cs similarity index 94% rename from test/DotNetty.NetUV.Tests/Handles/ActiveTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/ActiveTests.cs index a25afcc2a..fdec02689 100644 --- a/test/DotNetty.NetUV.Tests/Handles/ActiveTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/ActiveTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class ActiveTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/AsyncTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/AsyncTests.cs similarity index 94% rename from test/DotNetty.NetUV.Tests/Handles/AsyncTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/AsyncTests.cs index a17103d2c..ba9160b50 100644 --- a/test/DotNetty.NetUV.Tests/Handles/AsyncTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/AsyncTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Threading; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class AsyncTests : IDisposable @@ -52,7 +52,7 @@ void OnAsync(Async handle) this.async.CloseHandle(this.OnClose); } - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/CallbackOrderTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/CallbackOrderTests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/CallbackOrderTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/CallbackOrderTests.cs index 6dc62e360..4f7029e05 100644 --- a/test/DotNetty.NetUV.Tests/Handles/CallbackOrderTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/CallbackOrderTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class CallbackOrderTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/CloseOrderTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/CloseOrderTests.cs similarity index 93% rename from test/DotNetty.NetUV.Tests/Handles/CloseOrderTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/CloseOrderTests.cs index 48c1b4a23..a676f0051 100644 --- a/test/DotNetty.NetUV.Tests/Handles/CloseOrderTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/CloseOrderTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class CloseOrderTests : IDisposable @@ -66,7 +66,7 @@ void OnTimer(Timer timer) timer.CloseHandle(this.OnClose); } - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/ConnectionFailTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/ConnectionFailTests.cs similarity index 96% rename from test/DotNetty.NetUV.Tests/Handles/ConnectionFailTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/ConnectionFailTests.cs index 06c31d99a..a56069287 100644 --- a/test/DotNetty.NetUV.Tests/Handles/ConnectionFailTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/ConnectionFailTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class ConnectionFailTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/FSEventTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/FSEventTests.cs similarity index 98% rename from test/DotNetty.NetUV.Tests/Handles/FSEventTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/FSEventTests.cs index 4036c71ad..bf4b0381e 100644 --- a/test/DotNetty.NetUV.Tests/Handles/FSEventTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/FSEventTests.cs @@ -1,12 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Collections.Generic; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class FSEventTests : IDisposable @@ -456,7 +457,7 @@ public void GetPath() Assert.Equal(1, this.closeCount); } - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/FSPollTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/FSPollTests.cs similarity index 96% rename from test/DotNetty.NetUV.Tests/Handles/FSPollTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/FSPollTests.cs index a1d8798a2..932143c03 100644 --- a/test/DotNetty.NetUV.Tests/Handles/FSPollTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/FSPollTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Collections.Generic; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class FSPollTests : IDisposable @@ -152,7 +152,7 @@ public void GetPath() void OnFSPoll(FSPoll fsPoll, FSPollStatus fsPollStatus) => this.callbackCount++; - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/GetAddrInfoTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/GetAddrInfoTests.cs similarity index 94% rename from test/DotNetty.NetUV.Tests/Handles/GetAddrInfoTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/GetAddrInfoTests.cs index 0683ba5b9..82e650394 100644 --- a/test/DotNetty.NetUV.Tests/Handles/GetAddrInfoTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/GetAddrInfoTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Requests; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Requests; using Xunit; public sealed class GetAddrInfoTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/GetNameInfoTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/GetNameInfoTests.cs similarity index 90% rename from test/DotNetty.NetUV.Tests/Handles/GetNameInfoTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/GetNameInfoTests.cs index 7cefd8c6a..724770c1e 100644 --- a/test/DotNetty.NetUV.Tests/Handles/GetNameInfoTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/GetNameInfoTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Requests; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Requests; using Xunit; public sealed class GetNameInfoTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/GetSockNameTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/GetSockNameTests.cs similarity index 96% rename from test/DotNetty.NetUV.Tests/Handles/GetSockNameTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/GetSockNameTests.cs index 286667a0e..5dc11790c 100644 --- a/test/DotNetty.NetUV.Tests/Handles/GetSockNameTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/GetSockNameTests.cs @@ -1,14 +1,14 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; using DotNetty.Buffers; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class GetSockNameTests : IDisposable @@ -16,7 +16,7 @@ public sealed class GetSockNameTests : IDisposable const int Port = 9881; Loop loop; - ScheduleHandle server; + IScheduleHandle server; int closeCount; int connectedCount; int connectionCount; @@ -159,7 +159,7 @@ void OnConnection(Tcp tcp, Exception exception) this.server.CloseHandle(this.OnClose); } - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/IdleTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/IdleTests.cs similarity index 91% rename from test/DotNetty.NetUV.Tests/Handles/IdleTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/IdleTests.cs index 32e111acc..7e86d941c 100644 --- a/test/DotNetty.NetUV.Tests/Handles/IdleTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/IdleTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class IdleTests : IDisposable @@ -48,7 +48,7 @@ public void IdleStarvation() Assert.Equal(3, this.closeCount); } - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/LoopAliveTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopAliveTests.cs similarity index 92% rename from test/DotNetty.NetUV.Tests/Handles/LoopAliveTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/LoopAliveTests.cs index 0fb277ba0..1dc797a87 100644 --- a/test/DotNetty.NetUV.Tests/Handles/LoopAliveTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopAliveTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Requests; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Requests; using Xunit; public sealed class LoopAliveTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/LoopHandleTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopHandleTests.cs similarity index 98% rename from test/DotNetty.NetUV.Tests/Handles/LoopHandleTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/LoopHandleTests.cs index a632f0326..80a9d493f 100644 --- a/test/DotNetty.NetUV.Tests/Handles/LoopHandleTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopHandleTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; /* diff --git a/test/DotNetty.NetUV.Tests/Handles/LoopRunNoWaitTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopRunNoWaitTests.cs similarity index 90% rename from test/DotNetty.NetUV.Tests/Handles/LoopRunNoWaitTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/LoopRunNoWaitTests.cs index 2ef7bfbaa..6c42dd048 100644 --- a/test/DotNetty.NetUV.Tests/Handles/LoopRunNoWaitTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopRunNoWaitTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class LoopRunNoWaitTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/LoopRunOnceTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopRunOnceTests.cs similarity index 92% rename from test/DotNetty.NetUV.Tests/Handles/LoopRunOnceTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/LoopRunOnceTests.cs index 93deb876e..a13cb08d3 100644 --- a/test/DotNetty.NetUV.Tests/Handles/LoopRunOnceTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopRunOnceTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class LoopRunOnceTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/LoopStopTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopStopTests.cs similarity index 94% rename from test/DotNetty.NetUV.Tests/Handles/LoopStopTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/LoopStopTests.cs index 71ceaa48e..3dc0492d2 100644 --- a/test/DotNetty.NetUV.Tests/Handles/LoopStopTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopStopTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class LoopStopTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/LoopTimeTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopTimeTests.cs similarity index 93% rename from test/DotNetty.NetUV.Tests/Handles/LoopTimeTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/LoopTimeTests.cs index de842486f..a6125c4cb 100644 --- a/test/DotNetty.NetUV.Tests/Handles/LoopTimeTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/LoopTimeTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class LoopTimeTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/MultipleListenTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/MultipleListenTests.cs similarity index 96% rename from test/DotNetty.NetUV.Tests/Handles/MultipleListenTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/MultipleListenTests.cs index c9a495da1..ccc79f875 100644 --- a/test/DotNetty.NetUV.Tests/Handles/MultipleListenTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/MultipleListenTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class MultipleListenTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/PipeBindErrorTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeBindErrorTests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/PipeBindErrorTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PipeBindErrorTests.cs index f9c6720f6..8ddcd5a48 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PipeBindErrorTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeBindErrorTests.cs @@ -1,11 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class PipeBindErrorTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/PipeConnectErrorTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectErrorTests.cs similarity index 91% rename from test/DotNetty.NetUV.Tests/Handles/PipeConnectErrorTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectErrorTests.cs index 72a8dc561..e2564cd94 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PipeConnectErrorTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectErrorTests.cs @@ -1,11 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class PipeConnectErrorTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/PipeConnectMultipleTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectMultipleTests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/PipeConnectMultipleTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectMultipleTests.cs index 8bd7b5f42..9e16854a3 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PipeConnectMultipleTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectMultipleTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Collections.Generic; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class PipeConnectMultipleTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/PipeConnectPrepareTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectPrepareTests.cs similarity index 89% rename from test/DotNetty.NetUV.Tests/Handles/PipeConnectPrepareTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectPrepareTests.cs index ff64e808a..aa3863291 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PipeConnectPrepareTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeConnectPrepareTests.cs @@ -1,11 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class PipeConnectPrepareTests : IDisposable @@ -53,7 +54,7 @@ static string GetBadPipeName() => ? "bad-pipe" : "/path/to/unix/socket/that/really/should/not/be/there"; - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/PipeGetSockNameTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeGetSockNameTests.cs similarity index 93% rename from test/DotNetty.NetUV.Tests/Handles/PipeGetSockNameTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PipeGetSockNameTests.cs index 75e95ed90..d483a17f8 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PipeGetSockNameTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeGetSockNameTests.cs @@ -1,11 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class PipeGetSockNameTests : IDisposable @@ -74,7 +75,7 @@ void OnConnected(Pipe pipe, Exception exception) pipe.CloseHandle(this.OnClose); } - void OnClose(StreamHandle handle) + void OnClose(IStreamHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/PipePendingInstancesTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PipePendingInstancesTests.cs similarity index 91% rename from test/DotNetty.NetUV.Tests/Handles/PipePendingInstancesTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PipePendingInstancesTests.cs index 767801fd4..1210a0bc2 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PipePendingInstancesTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PipePendingInstancesTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class PipePendingInstancesTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/PipeServerCloseTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeServerCloseTests.cs similarity index 92% rename from test/DotNetty.NetUV.Tests/Handles/PipeServerCloseTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PipeServerCloseTests.cs index 25588900e..59f8fc40f 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PipeServerCloseTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PipeServerCloseTests.cs @@ -1,11 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class PipeServerCloseTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/PollCloseSocketTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PollCloseSocketTests.cs similarity index 94% rename from test/DotNetty.NetUV.Tests/Handles/PollCloseSocketTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PollCloseSocketTests.cs index 2d171924d..e8ead7f3b 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PollCloseSocketTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PollCloseSocketTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Net.Sockets; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class PollCloseSocketTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/PollCloseTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PollCloseTests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/PollCloseTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PollCloseTests.cs index f5fbbf170..874285067 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PollCloseTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PollCloseTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Collections.Generic; using System.Net.Sockets; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class PollCloseTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/PollTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/PollTests.cs similarity index 98% rename from test/DotNetty.NetUV.Tests/Handles/PollTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/PollTests.cs index 123245a0a..130645c77 100644 --- a/test/DotNetty.NetUV.Tests/Handles/PollTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/PollTests.cs @@ -1,14 +1,15 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.IO; using System.Net; using System.Net.Sockets; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class PollTests : IDisposable @@ -425,7 +426,7 @@ static void DestroyServerContext(ServerContext context) context.Handle.CloseHandle(OnClose); } - static void OnClose(ScheduleHandle handle) => handle.Dispose(); + static void OnClose(IScheduleHandle handle) => handle.Dispose(); void DestroyConnectionContext(ConnectionContext context) { @@ -434,7 +435,7 @@ void DestroyConnectionContext(ConnectionContext context) context.TimerHandle.CloseHandle(this.OnConnectionClosed); } - void OnConnectionClosed(ScheduleHandle handle) + void OnConnectionClosed(IScheduleHandle handle) { var context = (ConnectionContext)handle.UserToken; context.OpenHandles--; diff --git a/test/DotNetty.NetUV.Tests/Handles/RefTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/RefTests.cs similarity index 87% rename from test/DotNetty.NetUV.Tests/Handles/RefTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/RefTests.cs index cbd4af0c8..c3c5b3f87 100644 --- a/test/DotNetty.NetUV.Tests/Handles/RefTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/RefTests.cs @@ -1,13 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class RefTests : IDisposable @@ -207,7 +207,7 @@ public void TcpListen2() Assert.Equal(1, this.closeCount); } - void OnConnection(StreamHandle stream, Exception exception) => this.callbackCount++; + void OnConnection(Tcp stream, Exception exception) => this.callbackCount++; [Fact] public void TcpConnectNoServer() @@ -224,13 +224,13 @@ public void TcpConnectNoServer() this.CloseHandle(tcp); } - void OnConnectedAndShutdown(StreamHandle stream, Exception exception) + void OnConnectedAndShutdown(Tcp stream, Exception exception) { stream.Shutdown(this.OnShutdown); this.callbackCount++; } - void OnShutdown(StreamHandle handle, Exception exception) => this.callbackCount++; + void OnShutdown(Tcp handle, Exception exception) => this.callbackCount++; [Fact] public void TcpConnect2NoServer() @@ -247,7 +247,7 @@ public void TcpConnect2NoServer() this.CloseHandle(tcp); } - void OnConnectedAndWrite(StreamHandle handle, Exception exception) + void OnConnectedAndWrite(Tcp handle, Exception exception) { this.callbackCount++; if (exception == null) @@ -257,7 +257,7 @@ void OnConnectedAndWrite(StreamHandle handle, Exception exception) } } - void OnWriteCompleted(StreamHandle handle, Exception exception) => this.callbackCount++; + void OnWriteCompleted(Tcp handle, Exception exception) => this.callbackCount++; [Fact] public void Pipe() @@ -300,6 +300,8 @@ public void PipeListen2() pipe.CloseHandle(this.OnClose); } + void OnConnection(Pipe stream, Exception exception) => this.callbackCount++; + [Fact] public void PipeConnectNoServer() { @@ -328,6 +330,26 @@ public void PipeConnect2NoServer() this.CloseHandle(pipe); } + void OnConnectedAndShutdown(Pipe stream, Exception exception) + { + stream.Shutdown(this.OnShutdown); + this.callbackCount++; + } + + void OnShutdown(Pipe handle, Exception exception) => this.callbackCount++; + + void OnConnectedAndWrite(Pipe handle, Exception exception) + { + this.callbackCount++; + if (exception == null) + { + var data = new byte[1]; + handle.QueueWriteStream(data, 0, data.Length, this.OnWriteCompleted); + } + } + + void OnWriteCompleted(Pipe handle, Exception exception) => this.callbackCount++; + static string GetPipeName() => Platform.IsWindows ? "\\\\?\\pipe\\uv-test5" : "/tmp/uv-test5-sock"; @@ -379,16 +401,16 @@ public void UdpSend() void OnSendCompleted(Udp udp, Exception exception) => this.callbackCount++; - void CloseHandle(ScheduleHandle handle) + void CloseHandle(IScheduleHandle handle) { handle.CloseHandle(this.OnClose); this.loop.RunDefault(); Assert.Equal(1, this.closeCount); } - void OnCallback(ScheduleHandle handle) => this.callbackCount++; + void OnCallback(IScheduleHandle handle) => this.callbackCount++; - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/TcpBind6ErrorTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpBind6ErrorTests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/TcpBind6ErrorTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TcpBind6ErrorTests.cs index dcb55c8a8..d687d7f30 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TcpBind6ErrorTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpBind6ErrorTests.cs @@ -1,12 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class TcpBind6ErrorTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/TcpBindErrorTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpBindErrorTests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/TcpBindErrorTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TcpBindErrorTests.cs index bc2441bb3..6a26c5fef 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TcpBindErrorTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpBindErrorTests.cs @@ -1,12 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class TcpBindErrorTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/TcpCloseTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpCloseTests.cs similarity index 96% rename from test/DotNetty.NetUV.Tests/Handles/TcpCloseTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TcpCloseTests.cs index fdfee920a..b0415131f 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TcpCloseTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpCloseTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class TcpCloseTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/TcpCloseWhileConnectingTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpCloseWhileConnectingTests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/TcpCloseWhileConnectingTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TcpCloseWhileConnectingTests.cs index f996b5609..d4eb0fd45 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TcpCloseWhileConnectingTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpCloseWhileConnectingTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class TcpCloseWhileConnectingTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/TcpConnectTimeoutTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpConnectTimeoutTests.cs similarity index 94% rename from test/DotNetty.NetUV.Tests/Handles/TcpConnectTimeoutTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TcpConnectTimeoutTests.cs index 382ba2bba..1ff5b75e7 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TcpConnectTimeoutTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpConnectTimeoutTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class TcpConnectTimeoutTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/TcpFlagsTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpFlagsTests.cs similarity index 89% rename from test/DotNetty.NetUV.Tests/Handles/TcpFlagsTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TcpFlagsTests.cs index 060acf0ba..b96a57126 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TcpFlagsTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpFlagsTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class TcpFlagsTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/TcpTryWriteTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpTryWriteTests.cs similarity index 96% rename from test/DotNetty.NetUV.Tests/Handles/TcpTryWriteTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TcpTryWriteTests.cs index 6dbc40dd7..42608f4be 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TcpTryWriteTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TcpTryWriteTests.cs @@ -1,13 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class TcpTryWriteTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/TestHelper.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TestHelper.cs similarity index 99% rename from test/DotNetty.NetUV.Tests/Handles/TestHelper.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TestHelper.cs index f76fb7236..05889fa6f 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TestHelper.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TestHelper.cs @@ -1,7 +1,7 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Collections.Generic; diff --git a/test/DotNetty.NetUV.Tests/Handles/TimerTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TimerTests.cs similarity index 98% rename from test/DotNetty.NetUV.Tests/Handles/TimerTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TimerTests.cs index df97f7189..537cd65dd 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TimerTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TimerTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Collections.Generic; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class TimerTests : IDisposable @@ -290,7 +290,7 @@ public void EarlyCheck() Assert.Equal(0, result); } - static void OnClose(ScheduleHandle handle) => handle.Dispose(); + static void OnClose(IScheduleHandle handle) => handle.Dispose(); public void Dispose() { diff --git a/test/DotNetty.NetUV.Tests/Handles/TtyTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/TtyTests.cs similarity index 93% rename from test/DotNetty.NetUV.Tests/Handles/TtyTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/TtyTests.cs index f896f6df7..dbca7deaa 100644 --- a/test/DotNetty.NetUV.Tests/Handles/TtyTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/TtyTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class TtyTests : IDisposable @@ -21,7 +21,7 @@ public TtyTests() [Fact] public void Types() { - if (Platform.IsWindows + if (Platform.IsWindows || Platform.IsDarwin) { return; diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpBindTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpBindTests.cs similarity index 91% rename from test/DotNetty.NetUV.Tests/Handles/UdpBindTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpBindTests.cs index 367f5dbf6..1959a1c20 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpBindTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpBindTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class UdpBindTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpDatagramTooBigTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpDatagramTooBigTests.cs similarity index 92% rename from test/DotNetty.NetUV.Tests/Handles/UdpDatagramTooBigTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpDatagramTooBigTests.cs index 19403e4bd..e538c9c97 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpDatagramTooBigTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpDatagramTooBigTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class UdpDatagramTooBigTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpIPv6Tests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpIPv6Tests.cs similarity index 85% rename from test/DotNetty.NetUV.Tests/Handles/UdpIPv6Tests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpIPv6Tests.cs index bc01be210..cf893fdc6 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpIPv6Tests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpIPv6Tests.cs @@ -1,13 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class UdpIPv6Tests : IDisposable @@ -72,7 +72,7 @@ void OnSendCompleted(Udp udp, Exception exception) void OnReceive(Udp udp, IDatagramReadCompletion completion) { - if (completion.Error == null + if (completion.Error == null && completion.Data.Count > 0) { this.receiveCount++; @@ -81,12 +81,12 @@ void OnReceive(Udp udp, IDatagramReadCompletion completion) void OnTimer(Timer handle) { - this.server?.CloseHandle(this.OnClose); - this.client?.CloseHandle(this.OnClose); - handle.CloseHandle(this.OnClose); + this.server?.CloseHandle(h => this.OnClose(h)); + this.client?.CloseHandle(h => this.OnClose(h)); + handle.CloseHandle(h => this.OnClose(h)); } - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastInterface6Tests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastInterface6Tests.cs similarity index 93% rename from test/DotNetty.NetUV.Tests/Handles/UdpMulticastInterface6Tests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastInterface6Tests.cs index 7afbe5326..7e45186e6 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastInterface6Tests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastInterface6Tests.cs @@ -1,13 +1,14 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class UdpMulticastInterface6Tests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastInterfaceTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastInterfaceTests.cs similarity index 94% rename from test/DotNetty.NetUV.Tests/Handles/UdpMulticastInterfaceTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastInterfaceTests.cs index 615b91231..eeccb2f23 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastInterfaceTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastInterfaceTests.cs @@ -1,13 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class UdpMulticastInterfaceTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastJoin6Tests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastJoin6Tests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/UdpMulticastJoin6Tests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastJoin6Tests.cs index d2ed0a2dd..3d16dcb15 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastJoin6Tests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastJoin6Tests.cs @@ -1,14 +1,15 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; using DotNetty.Buffers; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class UdpMulticastJoin6Tests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastJoinTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastJoinTests.cs similarity index 96% rename from test/DotNetty.NetUV.Tests/Handles/UdpMulticastJoinTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastJoinTests.cs index caa9c364b..511c22192 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastJoinTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastJoinTests.cs @@ -1,13 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; using DotNetty.Buffers; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class UdpMulticastJoinTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastTtlTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastTtlTests.cs similarity index 93% rename from test/DotNetty.NetUV.Tests/Handles/UdpMulticastTtlTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastTtlTests.cs index 572c00fb7..b61d83b27 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpMulticastTtlTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpMulticastTtlTests.cs @@ -1,13 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class UdpMulticastTtlTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpOptionsTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpOptionsTests.cs similarity index 95% rename from test/DotNetty.NetUV.Tests/Handles/UdpOptionsTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpOptionsTests.cs index ae9b21784..be41b93c7 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpOptionsTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpOptionsTests.cs @@ -1,13 +1,14 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Collections.Generic; using System.Net; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class UdpOptionsTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpSendAndReceiveTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendAndReceiveTests.cs similarity index 97% rename from test/DotNetty.NetUV.Tests/Handles/UdpSendAndReceiveTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendAndReceiveTests.cs index bb2f6b2d5..9f0dd911d 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpSendAndReceiveTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendAndReceiveTests.cs @@ -1,13 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; using DotNetty.Buffers; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class UdpSendAndReceiveTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpSendImmediateTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendImmediateTests.cs similarity index 96% rename from test/DotNetty.NetUV.Tests/Handles/UdpSendImmediateTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendImmediateTests.cs index cbbc685f7..9b7bc2c1a 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpSendImmediateTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendImmediateTests.cs @@ -1,13 +1,13 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; using DotNetty.Buffers; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class UdpSendImmediateTests : IDisposable diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpSendUnreachableTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendUnreachableTests.cs similarity index 90% rename from test/DotNetty.NetUV.Tests/Handles/UdpSendUnreachableTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendUnreachableTests.cs index e4d20b166..5f966f2e0 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpSendUnreachableTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpSendUnreachableTests.cs @@ -1,12 +1,12 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; - using DotNetty.NetUV.Handles; + using DotNetty.Transport.Libuv.Handles; using Xunit; public sealed class UdpSendUnreachableTests : IDisposable @@ -76,11 +76,11 @@ void OnSendCompleted(Udp udp, Exception exception) void OnTimer(Timer handle) { this.timerCount++; - this.client?.CloseHandle(this.OnClose); - handle.CloseHandle(this.OnClose); + this.client?.CloseHandle(h => this.OnClose(h)); + handle.CloseHandle(h => this.OnClose(h)); } - void OnClose(ScheduleHandle handle) + void OnClose(IScheduleHandle handle) { handle.Dispose(); this.closeCount++; diff --git a/test/DotNetty.NetUV.Tests/Handles/UdpTrySendTests.cs b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpTrySendTests.cs similarity index 93% rename from test/DotNetty.NetUV.Tests/Handles/UdpTrySendTests.cs rename to test/DotNetty.Transport.Libuv.Tests/Handles/UdpTrySendTests.cs index 6f85a17ac..e28825a7d 100644 --- a/test/DotNetty.NetUV.Tests/Handles/UdpTrySendTests.cs +++ b/test/DotNetty.Transport.Libuv.Tests/Handles/UdpTrySendTests.cs @@ -1,14 +1,15 @@ // Copyright (c) Johnny Z. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace DotNetty.NetUV.Tests.Handles +namespace DotNetty.Transport.Libuv.Tests.Handles { using System; using System.Net; using System.Text; using DotNetty.Buffers; - using DotNetty.NetUV.Handles; - using DotNetty.NetUV.Native; + using DotNetty.Common; + using DotNetty.Transport.Libuv.Handles; + using DotNetty.Transport.Libuv.Native; using Xunit; public sealed class UdpTrySendTests : IDisposable diff --git a/test/DotNetty.Transport.Libuv.Tests/ReadPendingTests.cs b/test/DotNetty.Transport.Libuv.Tests/ReadPendingTests.cs deleted file mode 100644 index 15bfb3553..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/ReadPendingTests.cs +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - using DotNetty.Buffers; - using DotNetty.Common.Concurrency; - using DotNetty.Common.Utilities; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class ReadPendingTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public ReadPendingTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void ReadPendingIsResetAfterEachRead() - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel(); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.ReadPendingIsResetAfterEachRead0(sb, cb); - } - - void ReadPendingIsResetAfterEachRead0(ServerBootstrap sb, Bootstrap cb) - { - var serverInitializer = new ReadPendingInitializer(); - sb.Option(ChannelOption.SoBacklog, 1024) - .Option(ChannelOption.AutoRead, true) - .ChildOption(ChannelOption.AutoRead, false) - // We intend to do 2 reads per read loop wakeup - .ChildOption(ChannelOption.RcvbufAllocator, new TestNumReadsRecvByteBufAllocator(2)) - .ChildHandler(serverInitializer); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - var clientInitializer = new ReadPendingInitializer(); - cb.Option(ChannelOption.AutoRead, false) - // We intend to do 2 reads per read loop wakeup - .Option(ChannelOption.RcvbufAllocator, new TestNumReadsRecvByteBufAllocator(2)) - .Handler(clientInitializer); - - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - // 4 bytes means 2 read loops for TestNumReadsRecvByteBufAllocator - Task writeTask = this.clientChannel.WriteAndFlushAsync(Unpooled.WrappedBuffer(new byte[4])); - Assert.True(writeTask.Wait(TimeSpan.FromSeconds(5)), "Client write task timed out"); - - // 4 bytes means 2 read loops for TestNumReadsRecvByteBufAllocator - Assert.True(serverInitializer.Initialize.Wait(DefaultTimeout), "Server initializer timed out"); - writeTask = serverInitializer.Channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(new byte[4])); - Assert.True(writeTask.Wait(TimeSpan.FromSeconds(5)), "Server write task timed out"); - - serverInitializer.Channel.Read(); - serverInitializer.ReadPendingHandler.AssertAllRead(); - - this.clientChannel.Read(); - clientInitializer.ReadPendingHandler.AssertAllRead(); - } - - sealed class ReadPendingInitializer : ChannelInitializer - { - internal readonly ReadPendingReadHandler ReadPendingHandler = new ReadPendingReadHandler(); - readonly DefaultPromise completionSource = new(); - internal volatile IChannel Channel; - - public Task Initialize => this.completionSource.Task; - - protected override void InitChannel(IChannel ch) - { - this.Channel = ch; - ch.Pipeline.AddLast(this.ReadPendingHandler); - this.completionSource.TryComplete(); - } - } - - sealed class ReadPendingReadHandler : ChannelHandlerAdapter - { - readonly CountdownEvent latch = new CountdownEvent(1); - readonly CountdownEvent latch2 = new CountdownEvent(2); - int count; - - public override void ChannelRead(IChannelHandlerContext ctx, object msg) - { - ReferenceCountUtil.Release(msg); - if (Interlocked.Increment(ref this.count) == 1) - { - // Call read the first time, to ensure it is not reset the second time. - ctx.Read(); - } - } - - public override void ChannelReadComplete(IChannelHandlerContext ctx) - { - if (!this.latch.IsSet) - { - this.latch.Signal(); - } - this.latch2.Signal(); - } - - public void AssertAllRead() - { - Assert.True(this.latch.Wait(TimeSpan.FromSeconds(5)), "First ChannelReadComplete timed out"); - - // We should only do 1 read loop, because we only called read() on the first channelRead. - Assert.True(this.latch2.Wait(TimeSpan.FromSeconds(5)), "Second ChannelReadComplete timed out"); - Assert.Equal(2, this.count); - } - } - - sealed class TestNumReadsRecvByteBufAllocator : IRecvByteBufAllocator - { - readonly int numReads; - - public TestNumReadsRecvByteBufAllocator(int numReads) - { - this.numReads = numReads; - } - - public IRecvByteBufAllocatorHandle NewHandle() => new AllocatorHandle(this.numReads); - - sealed class AllocatorHandle : IRecvByteBufAllocatorHandle - { - readonly int numReads; - int numMessagesRead; - - public AllocatorHandle(int numReads) - { - this.numReads = numReads; - } - - public IByteBuffer Allocate(IByteBufferAllocator alloc) => - alloc.Buffer(this.Guess(), this.Guess()); - - // only ever allocate buffers of size 1 to ensure the number of reads is controlled. - public int Guess() => 1; - - public void Reset(IChannelConfiguration config) - { - this.numMessagesRead = 0; - } - - public void IncMessagesRead(int numMessages) - { - this.numMessagesRead += numMessages; - } - - public int LastBytesRead { get; set; } - - public int AttemptedBytesRead { get; set; } - - public bool ContinueReading() - { - return this.numMessagesRead < this.numReads; - } - - public void ReadComplete() - { - // Nothing needs to be done or adjusted after each read cycle is completed. - } - } - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/ResetTests.cs b/test/DotNetty.Transport.Libuv.Tests/ResetTests.cs deleted file mode 100644 index 989963579..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/ResetTests.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - using DotNetty.Common.Concurrency; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using Xunit; - - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class ResetTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel serverChannel; - IChannel clientChannel; - - public ResetTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void ResetOnClose() - { - ServerBootstrap sb = new ServerBootstrap() - .Group(this.group) - .Channel(); - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.Run(sb, cb); - } - - void Run(ServerBootstrap sb, Bootstrap cb) - { - var serverInitializer = new ServerInitializer(); - sb.ChildHandler(serverInitializer); - - var clientInitializer = new ClientInitializer(); - cb.Handler(clientInitializer); - - // start server - Task task = sb.BindAsync(LoopbackAnyPort); - Assert.True(task.Wait(DefaultTimeout), "Server bind timed out"); - this.serverChannel = task.Result; - Assert.NotNull(this.serverChannel.LocalAddress); - var endPoint = (IPEndPoint)this.serverChannel.LocalAddress; - - // connect to server - task = cb.ConnectAsync(endPoint); - Assert.True(task.Wait(DefaultTimeout), "Connect to server timed out"); - this.clientChannel = task.Result; - Assert.NotNull(this.clientChannel.LocalAddress); - - Assert.True(serverInitializer.Initialized.Wait(DefaultTimeout), "Channel initialize timed out"); - Assert.True(serverInitializer.Close()); - - // Server connection closed will cause the client - // to receive EOF and the channel should go inactive - Assert.True(clientInitializer.Inactive.Wait(DefaultTimeout), "TcpChannel should fire Inactive if the server connection is closed."); - Assert.Null(clientInitializer.ErrorCaught); - } - - sealed class ServerInitializer : ChannelInitializer - { - readonly DefaultPromise completion; - IChannel serverChannel; - - public ServerInitializer() - { - this.completion = new DefaultPromise(); - } - - public Task Initialized => this.completion.Task; - - public bool Close() => this.serverChannel.CloseAsync().Wait(DefaultTimeout); - - protected override void InitChannel(IChannel channel) - { - if (Interlocked.CompareExchange(ref this.serverChannel, channel, null) == null) - { - this.completion.TryComplete(); - } - } - } - - sealed class ClientInitializer : ChannelInitializer - { - readonly ClientHandler handler; - - public ClientInitializer() - { - this.handler = new ClientHandler(); - } - - public Task Inactive => this.handler.Inactive; - - public Exception ErrorCaught => this.handler.Error; - - protected override void InitChannel(IChannel channel) => channel.Pipeline.AddLast(this.handler); - } - - sealed class ClientHandler : ChannelHandlerAdapter - { - readonly DefaultPromise completion; - internal Exception Error; - - public ClientHandler() - { - this.completion = new DefaultPromise(); - } - - public Task Inactive => this.completion.Task; - - public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) => - Interlocked.CompareExchange(ref this.Error, exception, null); - - public override void ChannelInactive(IChannelHandlerContext context) => this.completion.TryComplete(); - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.serverChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/TestUtil.cs b/test/DotNetty.Transport.Libuv.Tests/TestUtil.cs deleted file mode 100644 index cdeef28d2..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/TestUtil.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Net; - - static class TestUtil - { - // Unit test collection name, this is to avoid paralleled unit - // testing starting bind/listen on loopback at the same time - // on multiple threads (xunit default to the number of CPU cores) - // causing channel initial operations to timeout. - internal const string LibuvTransport = "Libuv Transport Tests"; - - internal static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(10); - - internal static readonly IPEndPoint LoopbackAnyPort = new IPEndPoint(IPAddress.IPv6Loopback, 0); - } -} diff --git a/test/DotNetty.Transport.Libuv.Tests/WriteBeforeRegisteredTests.cs b/test/DotNetty.Transport.Libuv.Tests/WriteBeforeRegisteredTests.cs deleted file mode 100644 index 2dafb9c57..000000000 --- a/test/DotNetty.Transport.Libuv.Tests/WriteBeforeRegisteredTests.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace DotNetty.Transport.Libuv.Tests -{ - using System; - using System.Threading.Tasks; - using DotNetty.Buffers; - using DotNetty.Transport.Bootstrapping; - using DotNetty.Transport.Channels; - using DotNetty.Transport.Libuv.Native; - using Xunit; - using static TestUtil; - - [Collection(LibuvTransport)] - public sealed class WriteBeforeRegisteredTests : IDisposable - { - readonly IEventLoopGroup group; - IChannel clientChannel; - - public WriteBeforeRegisteredTests() - { - this.group = new EventLoopGroup(1); - } - - [Fact] - public void WriteBeforeConnect() - { - Bootstrap cb = new Bootstrap() - .Group(this.group) - .Channel(); - this.WriteBeforeConnect0(cb); - } - - void WriteBeforeConnect0(Bootstrap cb) - { - var h = new TestHandler(); - cb.Handler(h); - - var task = (Task)cb.RegisterAsync(); - Assert.True(task.Wait(DefaultTimeout)); - this.clientChannel = task.Result; - - Task connectTask = this.clientChannel.ConnectAsync(LoopbackAnyPort); - Task writeTask = this.clientChannel.WriteAndFlushAsync(Unpooled.WrappedBuffer(new byte[] { 1 })); - var error = Assert.Throws(() => writeTask.Wait(DefaultTimeout)); - - Assert.Single(error.InnerExceptions); - Assert.IsType(error.InnerException); - Assert.Null(h.Error); - - // Connect task should fail - error = Assert.Throws(() => connectTask.Wait(DefaultTimeout)); - Assert.Single(error.InnerExceptions); - var innerException = error.InnerException; - if (error.InnerException is ChannelException channelException) - { - innerException = channelException.InnerException; - Assert.IsType(innerException); - var exception = (OperationException)innerException; - Assert.Equal("ECONNREFUSED", exception.Name); // ubuntu-18.04.2 - } - else - { - Assert.IsType(innerException); - var exception = (OperationException)innerException; - Assert.Equal("EADDRNOTAVAIL", exception.Name); // address not available (port : 0) - } - } - - sealed class TestHandler : ChannelHandlerAdapter - { - internal Exception Error; - - public override void ExceptionCaught(IChannelHandlerContext ctx, Exception exception) - { - this.Error = exception; - } - } - - public void Dispose() - { - this.clientChannel?.CloseAsync().Wait(DefaultTimeout); - this.group.ShutdownGracefullyAsync(TimeSpan.Zero, TimeSpan.Zero).Wait(DefaultTimeout); - } - } -}