├── tools
└── Key.snk
├── global.json
├── test
├── Channels.Tests.Performance
│ ├── random.json.gz
│ ├── project.json
│ ├── Channels.Tests.Performance.xproj
│ └── Program.cs
└── Channels.Tests
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── project.json
│ ├── Channels.Tests.xproj
│ ├── BufferPoolFacts.cs
│ ├── SignalFacts.cs
│ └── ReadableBufferReaderFacts.cs
├── README.md
├── NuGet.config
├── src
├── Channels
│ ├── IReadableBufferAwaiter.cs
│ ├── ChannelReadResult.cs
│ ├── StreamChannel.cs
│ ├── CommonVectors.cs
│ ├── IChannel.cs
│ ├── IBufferPool.cs
│ ├── ArrayBufferPool.cs
│ ├── project.json
│ ├── UnownedBuffer.cs
│ ├── ReadableChannelAwaitable.cs
│ ├── Channels.xproj
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── IWritableChannel.cs
│ ├── WritableChannel.cs
│ ├── PreservedBuffer.cs
│ ├── IReadableChannel.cs
│ ├── ReadableBufferReader.cs
│ ├── MemoryEnumerator.cs
│ ├── ReadableChannel.cs
│ ├── DefaultWritableBufferExtensions.cs
│ ├── ChannelFactory.cs
│ ├── Gate.cs
│ ├── MemoryPoolBlock.cs
│ ├── DefaultReadableBufferExtensions.cs
│ ├── MemoryPoolSlab.cs
│ └── WritableBuffer.cs
├── Channels.Networking.Windows.RIO
│ ├── Internal
│ │ ├── Winsock
│ │ │ ├── Protocol.cs
│ │ │ ├── SocketType.cs
│ │ │ ├── AddressFamilies.cs
│ │ │ ├── SuppressUnmanagedCodeSecurityAttribute.cs
│ │ │ ├── NotificationCompletionType.cs
│ │ │ ├── RioReceiveFlags.cs
│ │ │ ├── RioSendFlags.cs
│ │ │ ├── NotificationCompletion.cs
│ │ │ ├── NotificationCompletionEvent.cs
│ │ │ ├── SocketAddress.cs
│ │ │ ├── SocketFlags.cs
│ │ │ ├── NotificationCompletionIocp.cs
│ │ │ ├── Ipv4InternetAddress.cs
│ │ │ ├── WindowsSocketsData.cs
│ │ │ ├── RioExtensionFunctionTable.cs
│ │ │ ├── RegisteredIO.cs
│ │ │ ├── Version.cs
│ │ │ └── RioDelegates.cs
│ │ ├── RioRequestResult.cs
│ │ ├── RioBufferSegment.cs
│ │ └── RioThreadPool.cs
│ ├── project.json
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── Channels.Networking.Windows.RIO.xproj
├── Channels.Networking.Sockets
│ ├── Internal
│ │ ├── ContinuationMode.cs
│ │ ├── SocketExtensions.cs
│ │ ├── Signal.cs
│ │ └── MicroBufferPool.cs
│ ├── project.json
│ ├── Channels.Networking.Sockets.xproj
│ └── Properties
│ │ └── AssemblyInfo.cs
├── Channels.File
│ ├── project.json
│ ├── ReadableFileChannelFactoryExtensions.cs
│ └── Channels.File.xproj
├── Channels.Compression
│ ├── project.json
│ ├── Channels.Compression.xproj
│ ├── Interop
│ │ └── Interop.zlib.Unix.cs
│ ├── ZLibNative.Windows.cs
│ └── ZLibException.cs
├── Channels.Text.Primitives
│ ├── WritableChannelExtensions.cs
│ ├── project.json
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Channels.Text.Primitives.xproj
│ ├── WritableChannelFormatter.cs
│ ├── SplitEnumerable.cs
│ ├── SplitEnumerator.cs
│ └── AsciiUtilities.cs
└── Channels.Networking.Libuv
│ ├── Interop
│ ├── UvException.cs
│ ├── PlatformApis.cs
│ ├── UvRequest.cs
│ ├── UvPipeHandle.cs
│ ├── UvLoopHandle.cs
│ ├── UvShutdownReq.cs
│ ├── UvHandle.cs
│ ├── UvTcpHandle.cs
│ ├── UvAsyncHandle.cs
│ ├── UvMemory.cs
│ └── UvConnectRequest.cs
│ ├── project.json
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── Channels.Networking.Libuv.xproj
│ ├── Internal
│ ├── WriteReqPool.cs
│ └── WorkQueue.cs
│ ├── UvTcpClient.cs
│ ├── UvTcpListener.cs
│ └── UvThread.cs
├── .vscode
├── tasks.json
└── launch.json
├── .gitignore
├── samples
└── Channels.Samples
│ ├── Program.cs
│ ├── LibuvHttpClientSample.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── Models
│ └── Pet.cs
│ ├── project.json
│ ├── Channels.Samples.xproj
│ ├── CompressionSample.cs
│ ├── AspNetHttpServerSample.cs
│ ├── HttpServer
│ ├── FormReader.cs
│ ├── HttpResponseStream.cs
│ ├── ResponseHeaderDictionary.cs
│ ├── HttpRequestParser.cs
│ └── HttpConnection.Features.cs
│ ├── RawLibuvHttpClientSample.cs
│ ├── HttpClient
│ └── ChannelHttpContent.cs
│ ├── RawLibuvHttpServerSample.cs
│ └── Framing
│ └── Codec.cs
├── LICENSE.md
├── .gitattributes
├── appveyor.yml
└── .travis.yml
/tools/Key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidfowl/Channels/HEAD/tools/Key.snk
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "projects": [ "src", "test" ],
3 | "sdk": {
4 | "version": "1.0.0-preview2-003121"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/Channels.Tests.Performance/random.json.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidfowl/Channels/HEAD/test/Channels.Tests.Performance/random.json.gz
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Channels (Push based Streams)
2 |
3 | Channels has been renamed to Pipelines (System.IO.Pipelines) and has moved to corefxlab https://github.com/dotnet/corefxlab.
4 |
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/Channels/IReadableBufferAwaiter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Channels
4 | {
5 | public interface IReadableBufferAwaiter
6 | {
7 | bool IsCompleted { get; }
8 |
9 | ChannelReadResult GetResult();
10 |
11 | void OnCompleted(Action continuation);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/Protocol.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
5 | {
6 | public enum Protocol : short
7 | {
8 | IpProtocolTcp = 6,
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/SocketType.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
5 | {
6 | public enum SocketType : short
7 | {
8 | Stream = 1,
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/AddressFamilies.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
5 | {
6 | public enum AddressFamilies : short
7 | {
8 | Internet = 2,
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/SuppressUnmanagedCodeSecurityAttribute.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | #if !NET451
5 | namespace System.Security
6 | {
7 | public class SuppressUnmanagedCodeSecurityAttribute : Attribute
8 | {
9 | }
10 | }
11 | #endif
--------------------------------------------------------------------------------
/src/Channels/ChannelReadResult.cs:
--------------------------------------------------------------------------------
1 | namespace Channels
2 | {
3 | public struct ChannelReadResult
4 | {
5 | public ChannelReadResult(ReadableBuffer buffer, bool isCompleted)
6 | {
7 | Buffer = buffer;
8 | IsCompleted = isCompleted;
9 | }
10 |
11 | public ReadableBuffer Buffer { get; }
12 |
13 | public bool IsCompleted { get; }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Sockets/Internal/ContinuationMode.cs:
--------------------------------------------------------------------------------
1 | namespace Channels.Networking.Sockets.Internal
2 | {
3 | ///
4 | /// Used by Signal to control how callbacks are invoked
5 | ///
6 | internal enum ContinuationMode
7 | {
8 | Synchronous,
9 | ThreadPool,
10 | // TODO: sync-context? but if so: whose? the .Current at creation? at SetResult?
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0",
3 | "command": "dotnet",
4 | "isShellCommand": true,
5 | "args": [],
6 | "tasks": [
7 | {
8 | "taskName": "build",
9 | "args": [
10 | "${workspaceRoot}/samples/Channels.Samples/project.json"
11 | ],
12 | "isBuildCommand": true,
13 | "problemMatcher": "$msCompile"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/src/Channels.File/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0-*",
3 |
4 | "buildOptions": {
5 | "allowUnsafe": true,
6 | "keyFile": "../../tools/Key.snk",
7 | "xmlDoc": true
8 | },
9 |
10 | "dependencies": {
11 | "Channels": {
12 | "target": "project"
13 | },
14 | "System.Threading.Overlapped": "4.0.1"
15 | },
16 |
17 |
18 | "frameworks": {
19 | "netstandard1.3": { },
20 | "net46": {}
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Channels.Compression/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0-*",
3 |
4 | "buildOptions": {
5 | "allowUnsafe": true,
6 | "keyFile": "../../tools/Key.snk",
7 | "xmlDoc": true
8 | },
9 |
10 | "dependencies": {
11 | "Channels": {
12 | "target": "project"
13 | },
14 | "System.Diagnostics.Contracts": "4.0.1"
15 | },
16 |
17 |
18 | "frameworks": {
19 | "net451": {},
20 | "netstandard1.3": {}
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/NotificationCompletionType.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
5 | {
6 | public enum NotificationCompletionType : int
7 | {
8 | Polling = 0,
9 | EventCompletion = 1,
10 | IocpCompletion = 2
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/RioReceiveFlags.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
5 | {
6 | public enum RioReceiveFlags : uint
7 | {
8 | None = 0x00000000,
9 | DontNotify = 0x00000001,
10 | Defer = 0x00000002,
11 | Waitall = 0x00000004,
12 | CommitOnly = 0x00000008
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/RioSendFlags.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 |
6 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
7 | {
8 | [Flags]
9 | public enum RioSendFlags : uint
10 | {
11 | None = 0x00000000,
12 | DontNotify = 0x00000001,
13 | Defer = 0x00000002,
14 | CommitOnly = 0x00000008
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Channels.Text.Primitives/WritableChannelExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Text.Formatting;
4 | using System.Threading.Tasks;
5 |
6 | namespace Channels.Text.Primitives
7 | {
8 | public static class WritableChannelExtensions
9 | {
10 | public static WritableChannelFormatter GetFormatter(this IWritableChannel channel, EncodingData formattingData)
11 | {
12 | return new WritableChannelFormatter(channel, formattingData);
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | [Oo]bj/
2 | [Bb]in/
3 | TestResults/
4 | .nuget/
5 | *.sln.ide/
6 | _ReSharper.*/
7 | packages/
8 | artifacts/
9 | PublishProfiles/
10 | .vs/
11 | *.user
12 | *.suo
13 | *.cache
14 | *.docstates
15 | _ReSharper.*
16 | nuget.exe
17 | *net45.csproj
18 | *net451.csproj
19 | *k10.csproj
20 | *.psess
21 | *.vsp
22 | *.pidb
23 | *.userprefs
24 | *DS_Store
25 | *.ncrunchsolution
26 | *.*sdf
27 | *.ipch
28 | project.lock.json
29 | runtimes/
30 | .build/
31 | .testPublish/
32 | launchSettings.json
33 | *.tmp
34 | BDN.Auto/
35 | BenchmarkDotNet.Artifacts/
36 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/NotificationCompletion.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct NotificationCompletion
10 | {
11 | public NotificationCompletionType Type;
12 | public NotificationCompletionIocp Iocp;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/NotificationCompletionEvent.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
8 | {
9 | [StructLayout(LayoutKind.Sequential)]
10 | public struct NotificationCompletionEvent
11 | {
12 | public IntPtr EventHandle;
13 | public bool NotifyReset;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/samples/Channels.Samples/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Channels.Samples.Framing;
7 | using Channels.Text.Primitives;
8 |
9 | namespace Channels.Samples
10 | {
11 | public class Program
12 | {
13 | public static void Main(string[] args)
14 | {
15 | AspNetHttpServerSample.Run();
16 | // RawLibuvHttpServerSample.Run();
17 | // ProtocolHandling.Run();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Interop/UvException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 |
6 | namespace Channels.Networking.Libuv.Interop
7 | {
8 | public class UvException : Exception
9 | {
10 | public UvException(string message, int statusCode) : base(message)
11 | {
12 | StatusCode = statusCode;
13 | }
14 |
15 | public int StatusCode { get; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/RioRequestResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Channels.Networking.Windows.RIO.Internal
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct RioRequestResult
10 | {
11 | public int Status;
12 | public uint BytesTransferred;
13 | public long ConnectionCorrelation;
14 | public long RequestCorrelation;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/SocketAddress.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public unsafe struct SocketAddress
10 | {
11 | public AddressFamilies Family;
12 | public ushort Port;
13 | public Ipv4InternetAddress IpAddress;
14 | public fixed byte Padding[8];
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Channels.File/ReadableFileChannelFactoryExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace Channels.File
7 | {
8 | public static class ReadableFileChannelFactoryExtensions
9 | {
10 | public static IReadableChannel ReadFile(this ChannelFactory factory, string path)
11 | {
12 | var channel = factory.CreateChannel();
13 |
14 | var file = new ReadableFileChannel(channel);
15 | file.OpenReadFile(path);
16 | return file;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) David Fowler All rights reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"); you
4 | may not use this file except in compliance with the License. You may
5 | obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 | implied. See the License for the specific language governing permissions
13 | and limitations under the License.
14 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/SocketFlags.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
5 | {
6 | public enum SocketFlags : uint
7 | {
8 | Overlapped = 0x01,
9 | MultipointCRoot = 0x02,
10 | MultipointCLeaf = 0x04,
11 | MultipointDRoot = 0x08,
12 | MultipointDLeaf = 0x10,
13 | AccessSystemSecurity = 0x40,
14 | NoHandleInherit = 0x80,
15 | RegisteredIO = 0x100
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Channels/StreamChannel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace Channels
5 | {
6 | internal class StreamChannel : IChannel
7 | {
8 | public StreamChannel(ChannelFactory factory, Stream stream)
9 | {
10 | Input = factory.MakeReadableChannel(stream);
11 | Output = factory.MakeWriteableChannel(stream);
12 | }
13 |
14 | public IReadableChannel Input { get; }
15 |
16 | public IWritableChannel Output { get; }
17 |
18 | public void Dispose()
19 | {
20 | Input.Complete();
21 | Output.Complete();
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/NotificationCompletionIocp.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.Runtime.InteropServices;
6 | using System.Threading;
7 |
8 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
9 | {
10 | [StructLayout(LayoutKind.Sequential)]
11 | public unsafe struct NotificationCompletionIocp
12 | {
13 | public IntPtr IocpHandle;
14 | public ulong QueueCorrelation;
15 | public NativeOverlapped* Overlapped;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Channels/CommonVectors.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 | using System.Runtime.CompilerServices;
3 |
4 | namespace Channels
5 | {
6 | // Move to text library?
7 | internal class CommonVectors
8 | {
9 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
10 | public static Vector GetVector(byte vectorByte)
11 | {
12 | // Vector .ctor is a bit fussy to get working; however this always seems to work
13 | // https://github.com/dotnet/coreclr/issues/7459#issuecomment-253965670
14 | return Vector.AsVectorByte(new Vector(vectorByte * 0x0101010101010101ul));
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Channels/IChannel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Channels
4 | {
5 | ///
6 | /// Defines a class that provides a duplex channel from which data can be read from and written to.
7 | ///
8 | public interface IChannel : IDisposable
9 | {
10 | ///
11 | /// Gets the half of the duplex channel.
12 | ///
13 | IReadableChannel Input { get; }
14 |
15 | ///
16 | /// Gets the half of the duplex channel.
17 | ///
18 | IWritableChannel Output { get; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/Ipv4InternetAddress.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
7 | {
8 | [StructLayout(LayoutKind.Explicit, Size = 4)]
9 | public struct Ipv4InternetAddress
10 | {
11 | [FieldOffset(0)]
12 | public byte Byte1;
13 | [FieldOffset(1)]
14 | public byte Byte2;
15 | [FieldOffset(2)]
16 | public byte Byte3;
17 | [FieldOffset(3)]
18 | public byte Byte4;
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Channels/IBufferPool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Buffers;
3 |
4 | namespace Channels
5 | {
6 | ///
7 | /// An interface that represents a that channels will use to allocate memory.
8 | ///
9 | public interface IBufferPool : IDisposable
10 | {
11 | ///
12 | /// Leases a from the
13 | ///
14 | /// The size of the requested buffer
15 | /// A which is a wrapper around leased memory
16 | OwnedMemory Lease(int size);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0-beta-*",
3 | "description": "Networking implementation of Channels based on Libuv",
4 | "packOptions": {
5 | "projectUrl": "https://github.com/davidfowl/Channels"
6 | },
7 | "buildOptions": {
8 | "allowUnsafe": true,
9 | "keyFile": "../../tools/Key.snk"
10 | },
11 |
12 | "dependencies": {
13 | "NETStandard.Library": "1.6.0",
14 | "Channels": {
15 | "target": "project"
16 | },
17 | "Libuv": "1.9.0"
18 | },
19 |
20 | "frameworks": {
21 | "net451": {},
22 | "netstandard1.3": {
23 | "dependencies": {
24 | "System.Threading.Thread": "4.0.0"
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Channels.Text.Primitives/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0-beta-*",
3 | "description": "Primitives for dealing with reading and writing text to and from channels",
4 | "packOptions": {
5 | "projectUrl": "https://github.com/davidfowl/Channels"
6 | },
7 | "buildOptions": {
8 | "allowUnsafe": true,
9 | "keyFile": "../../tools/Key.snk",
10 | "xmlDoc": true
11 | },
12 |
13 | "dependencies": {
14 | "NETStandard.Library": "1.6.0",
15 | "System.Text.Formatting": "0.1.0-*",
16 | "System.Text.Primitives": "0.1.0-*",
17 | "Channels": {
18 | "target": "project"
19 | }
20 | },
21 |
22 | "frameworks": {
23 | "net451": {},
24 | "netstandard1.3": {}
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Interop/PlatformApis.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | namespace Channels.Networking.Libuv.Interop
7 | {
8 | public static class PlatformApis
9 | {
10 | static PlatformApis()
11 | {
12 | IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
13 | IsDarwin = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
14 | }
15 |
16 | public static bool IsWindows { get; }
17 |
18 | public static bool IsDarwin { get; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Sockets/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0-beta-*",
3 | "description": "Networking implementation of Channels based on System.Net.Socket using the SocketAsyncEventArgs API",
4 | "packOptions": {
5 | "projectUrl": "https://github.com/davidfowl/Channels"
6 | },
7 | "buildOptions": {
8 | "allowUnsafe": true,
9 | "keyFile": "../../tools/Key.snk"
10 | },
11 |
12 | "dependencies": {
13 | "NETStandard.Library": "1.6.0",
14 | "Channels": {
15 | "target": "project"
16 | }
17 | },
18 |
19 | "frameworks": {
20 | "net451": { },
21 | "netstandard1.3": {
22 | "dependencies": {
23 | "System.Threading.ThreadPool": "4.0.10"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/RioBufferSegment.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace Channels.Networking.Windows.RIO.Internal
8 | {
9 | [StructLayout(LayoutKind.Sequential)]
10 | public struct RioBufferSegment
11 | {
12 | public RioBufferSegment(IntPtr bufferId, uint offset, uint length)
13 | {
14 | BufferId = bufferId;
15 | Offset = offset;
16 | Length = length;
17 | }
18 |
19 | IntPtr BufferId;
20 | public readonly uint Offset;
21 | public uint Length;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/samples/Channels.Samples/LibuvHttpClientSample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.Http;
5 | using System.Threading.Tasks;
6 |
7 | namespace Channels.Samples
8 | {
9 | public class LibuvHttpClientSample
10 | {
11 | public static async Task Run()
12 | {
13 | var client = new HttpClient(new LibuvHttpClientHandler());
14 |
15 | while (true)
16 | {
17 | var response = await client.GetAsync("http://localhost:5000");
18 |
19 | Console.WriteLine(response);
20 |
21 | Console.WriteLine(await response.Content.ReadAsStringAsync());
22 |
23 | await Task.Delay(1000);
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Interop/UvRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Channels.Networking.Libuv.Interop
5 | {
6 | public class UvRequest : UvMemory
7 | {
8 | private GCHandle _pin;
9 |
10 | protected UvRequest() : base ()
11 | {
12 | }
13 |
14 | protected override bool ReleaseHandle()
15 | {
16 | DestroyMemory(handle);
17 | handle = IntPtr.Zero;
18 | return true;
19 | }
20 |
21 | public virtual void Pin()
22 | {
23 | _pin = GCHandle.Alloc(this, GCHandleType.Normal);
24 | }
25 |
26 | public virtual void Unpin()
27 | {
28 | _pin.Free();
29 | }
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/src/Channels/ArrayBufferPool.cs:
--------------------------------------------------------------------------------
1 | using System.Buffers;
2 |
3 | namespace Channels
4 | {
5 | public class ArrayBufferPool : IBufferPool
6 | {
7 | public static readonly ArrayBufferPool Instance = new ArrayBufferPool(ArrayPool.Shared);
8 |
9 | private readonly ArrayPool _pool;
10 |
11 | public ArrayBufferPool(ArrayPool pool)
12 | {
13 | _pool = pool;
14 | }
15 |
16 | public OwnedMemory Lease(int size)
17 | {
18 | // Unfortunately this allocates.... (we could pool the owned array objects though)
19 | return new OwnedArray(_pool.Rent(size));
20 | }
21 |
22 | public void Dispose()
23 | {
24 | // Nothing to do here
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Channels/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0-beta-*",
3 | "description": "An abstraction for doing efficient asynchronous IO",
4 | "packOptions": {
5 | "projectUrl": "https://github.com/davidfowl/Channels"
6 | },
7 | "buildOptions": {
8 | "allowUnsafe": true,
9 | "keyFile": "../../tools/Key.snk",
10 | "xmlDoc": true
11 | },
12 |
13 | "dependencies": {
14 | "NETStandard.Library": "1.6.0",
15 | "System.Slices": "0.1.0-*",
16 | "System.Binary": "0.1.0-*",
17 | "System.Buffers": "4.0.0",
18 | "System.Runtime.CompilerServices.Unsafe": "4.0.0",
19 | "System.Numerics.Vectors": "4.1.1",
20 | "System.Threading.Tasks.Extensions": "4.0.0",
21 | "System.Collections.Sequences": "0.1.0-*"
22 | },
23 |
24 | "frameworks": {
25 | "net451": {},
26 | "netstandard1.3": {}
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/WindowsSocketsData.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
8 | {
9 | [StructLayout(LayoutKind.Sequential)]
10 | internal struct WindowsSocketsData
11 | {
12 | internal short Version;
13 | internal short HighVersion;
14 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
15 | internal string Description;
16 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
17 | internal string SystemStatus;
18 | internal short MaxSockets;
19 | internal short MaxDatagramSize;
20 | internal IntPtr VendorInfo;
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0-beta-*",
3 | "description": "Networking implementation of Channels based on Windows RIO",
4 | "packOptions": {
5 | "projectUrl": "https://github.com/davidfowl/Channels"
6 | },
7 | "buildOptions": {
8 | "allowUnsafe": true,
9 | "keyFile": "../../tools/Key.snk"
10 | },
11 |
12 | "dependencies": {
13 | "Channels": {
14 | "target": "project"
15 | }
16 | },
17 |
18 | "frameworks": {
19 | "net451": {},
20 | "netstandard1.3": {
21 | "dependencies": {
22 | "NETStandard.Library": "1.6.0",
23 | "System.Threading.Thread": "4.0.0",
24 | "System.Threading.Overlapped": "4.0.1",
25 | "System.Threading.ThreadPool": "4.0.10",
26 | "System.Diagnostics.Process": "4.1.0",
27 | "System.Runtime.CompilerServices.Unsafe": "4.0.0"
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/Channels.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("Channels.Tests")]
11 | [assembly: AssemblyTrademark("")]
12 |
13 | // Setting ComVisible to false makes the types in this assembly not visible
14 | // to COM components. If you need to access a type in this assembly from
15 | // COM, set the ComVisible attribute to true on that type.
16 | [assembly: ComVisible(false)]
17 |
18 | // The following GUID is for the ID of the typelib if this project is exposed to COM
19 | [assembly: Guid("b9967782-565b-4b0b-97b9-043e35022674")]
20 |
--------------------------------------------------------------------------------
/samples/Channels.Samples/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("Channels.Samples")]
11 | [assembly: AssemblyTrademark("")]
12 |
13 | // Setting ComVisible to false makes the types in this assembly not visible
14 | // to COM components. If you need to access a type in this assembly from
15 | // COM, set the ComVisible attribute to true on that type.
16 | [assembly: ComVisible(false)]
17 |
18 | // The following GUID is for the ID of the typelib if this project is exposed to COM
19 | [assembly: Guid("3dcb0f92-51ae-493e-a1b6-5b42449ea2bd")]
20 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("Channels.Networking.Libuv")]
11 | [assembly: AssemblyTrademark("")]
12 |
13 | // Setting ComVisible to false makes the types in this assembly not visible
14 | // to COM components. If you need to access a type in this assembly from
15 | // COM, set the ComVisible attribute to true on that type.
16 | [assembly: ComVisible(false)]
17 |
18 | // The following GUID is for the ID of the typelib if this project is exposed to COM
19 | [assembly: Guid("11d6b886-a303-4d13-bca8-a917d5740fb6")]
20 |
--------------------------------------------------------------------------------
/src/Channels.Text.Primitives/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("Channels.Text.Primitives")]
11 | [assembly: AssemblyTrademark("")]
12 |
13 | // Setting ComVisible to false makes the types in this assembly not visible
14 | // to COM components. If you need to access a type in this assembly from
15 | // COM, set the ComVisible attribute to true on that type.
16 | [assembly: ComVisible(false)]
17 |
18 | // The following GUID is for the ID of the typelib if this project is exposed to COM
19 | [assembly: Guid("a98068ae-c895-4b1f-adcb-60c70c64f118")]
20 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("Channels.Networking.Windows.RIO")]
11 | [assembly: AssemblyTrademark("")]
12 |
13 | // Setting ComVisible to false makes the types in this assembly not visible
14 | // to COM components. If you need to access a type in this assembly from
15 | // COM, set the ComVisible attribute to true on that type.
16 | [assembly: ComVisible(false)]
17 |
18 | // The following GUID is for the ID of the typelib if this project is exposed to COM
19 | [assembly: Guid("86a0b10d-8c7a-4b20-a033-d6f679454e30")]
20 |
--------------------------------------------------------------------------------
/src/Channels/UnownedBuffer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Buffers;
3 |
4 | namespace Channels
5 | {
6 | ///
7 | /// Represents a buffer that is owned by an external component.
8 | ///
9 | public class UnownedBuffer : OwnedMemory
10 | {
11 | private ArraySegment _buffer;
12 |
13 | public UnownedBuffer(ArraySegment buffer) : base(buffer.Array, buffer.Offset, buffer.Count)
14 | {
15 | _buffer = buffer;
16 | }
17 |
18 | public OwnedMemory MakeCopy(int offset, int length, out int newStart, out int newEnd)
19 | {
20 | // Copy to a new Owned Buffer.
21 | var buffer = new byte[length];
22 | Buffer.BlockCopy(_buffer.Array, _buffer.Offset + offset, buffer, 0, length);
23 | newStart = 0;
24 | newEnd = length;
25 | return new OwnedArray(buffer);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Channels/ReadableChannelAwaitable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.CompilerServices;
3 |
4 | namespace Channels
5 | {
6 | ///
7 | /// An awaitable object that represents an asynchronous read operation
8 | ///
9 | public struct ReadableChannelAwaitable : ICriticalNotifyCompletion
10 | {
11 | private readonly IReadableBufferAwaiter _awaiter;
12 |
13 | public ReadableChannelAwaitable(IReadableBufferAwaiter awaiter)
14 | {
15 | _awaiter = awaiter;
16 | }
17 |
18 | public bool IsCompleted => _awaiter.IsCompleted;
19 |
20 | public ChannelReadResult GetResult() => _awaiter.GetResult();
21 |
22 | public ReadableChannelAwaitable GetAwaiter() => this;
23 |
24 | public void UnsafeOnCompleted(Action continuation) => _awaiter.OnCompleted(continuation);
25 |
26 | public void OnCompleted(Action continuation) => _awaiter.OnCompleted(continuation);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Interop/UvPipeHandle.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 |
6 | namespace Channels.Networking.Libuv.Interop
7 | {
8 | public class UvPipeHandle : UvStreamHandle
9 | {
10 | public UvPipeHandle() : base()
11 | {
12 | }
13 |
14 | public void Init(UvLoopHandle loop, Action, IntPtr> queueCloseHandle, bool ipc = false)
15 | {
16 | CreateHandle(
17 | loop.Libuv,
18 | loop.ThreadId,
19 | loop.Libuv.handle_size(Uv.HandleType.NAMED_PIPE), queueCloseHandle);
20 |
21 | _uv.pipe_init(loop, this, ipc);
22 | }
23 |
24 | public void Bind(string name)
25 | {
26 | _uv.pipe_bind(this, name);
27 | }
28 |
29 | public int PendingCount()
30 | {
31 | return _uv.pipe_pending_count(this);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/RioExtensionFunctionTable.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
8 | {
9 | [StructLayout(LayoutKind.Sequential)]
10 | public struct RioExtensionFunctionTable
11 | {
12 | public UInt32 Size;
13 |
14 | public IntPtr RIOReceive;
15 | public IntPtr RIOReceiveEx;
16 | public IntPtr RIOSend;
17 | public IntPtr RIOSendEx;
18 | public IntPtr RIOCloseCompletionQueue;
19 | public IntPtr RIOCreateCompletionQueue;
20 | public IntPtr RIOCreateRequestQueue;
21 | public IntPtr RIODequeueCompletion;
22 | public IntPtr RIODeregisterBuffer;
23 | public IntPtr RIONotify;
24 | public IntPtr RIORegisterBuffer;
25 | public IntPtr RIOResizeCompletionQueue;
26 | public IntPtr RIOResizeRequestQueue;
27 | }
28 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.doc diff=astextplain
2 | *.DOC diff=astextplain
3 | *.docx diff=astextplain
4 | *.DOCX diff=astextplain
5 | *.dot diff=astextplain
6 | *.DOT diff=astextplain
7 | *.pdf diff=astextplain
8 | *.PDF diff=astextplain
9 | *.rtf diff=astextplain
10 | *.RTF diff=astextplain
11 |
12 | *.jpg binary
13 | *.png binary
14 | *.gif binary
15 |
16 | *.cs text=auto diff=csharp
17 | *.vb text=auto
18 | *.resx text=auto
19 | *.c text=auto
20 | *.cpp text=auto
21 | *.cxx text=auto
22 | *.h text=auto
23 | *.hxx text=auto
24 | *.py text=auto
25 | *.rb text=auto
26 | *.java text=auto
27 | *.html text=auto
28 | *.htm text=auto
29 | *.css text=auto
30 | *.scss text=auto
31 | *.sass text=auto
32 | *.less text=auto
33 | *.js text=auto
34 | *.lisp text=auto
35 | *.clj text=auto
36 | *.sql text=auto
37 | *.php text=auto
38 | *.lua text=auto
39 | *.m text=auto
40 | *.asm text=auto
41 | *.erl text=auto
42 | *.fs text=auto
43 | *.fsx text=auto
44 | *.hs text=auto
45 |
46 | *.csproj text=auto
47 | *.vbproj text=auto
48 | *.fsproj text=auto
49 | *.dbproj text=auto
50 | *.sln text=auto eol=crlf
51 |
52 | *.sh eol=lf
--------------------------------------------------------------------------------
/samples/Channels.Samples/Models/Pet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace Channels.Samples.Models
7 | {
8 | public class Pet
9 | {
10 | public int Id { get; set; }
11 |
12 | public int Age { get; set; }
13 |
14 | public Category Category { get; set; }
15 |
16 | public bool HasVaccinations { get; set; }
17 |
18 | public string Name { get; set; }
19 |
20 | public List Images { get; set; }
21 |
22 | public List Tags { get; set; }
23 |
24 | public string Status { get; set; }
25 | }
26 |
27 | public class Image
28 | {
29 | public int Id { get; set; }
30 |
31 | public string Url { get; set; }
32 | }
33 |
34 | public class Tag
35 | {
36 | public int Id { get; set; }
37 |
38 | public string Name { get; set; }
39 | }
40 |
41 | public class Category
42 | {
43 | public int Id { get; set; }
44 |
45 | public string Name { get; set; }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | os: Visual Studio 2015
2 | build: off
3 |
4 | before_test:
5 | - dotnet --info
6 | - dotnet restore
7 |
8 | test_script:
9 | # Build sample
10 | - dotnet build samples/Channels.Samples
11 | - dotnet test test/Channels.Tests
12 |
13 | after_test:
14 | # Build and pack source
15 | - dotnet pack -c Release src/Channels --version-suffix %APPVEYOR_BUILD_NUMBER%
16 | - dotnet pack -c Release src/Channels.Networking.Libuv --version-suffix %APPVEYOR_BUILD_NUMBER%
17 | - dotnet pack -c Release src/Channels.Networking.Windows.RIO --version-suffix %APPVEYOR_BUILD_NUMBER%
18 | - dotnet pack -c Release src/Channels.Networking.Sockets --version-suffix %APPVEYOR_BUILD_NUMBER%
19 | - dotnet pack -c Release src/Channels.Text.Primitives --version-suffix %APPVEYOR_BUILD_NUMBER%
20 |
21 |
22 | artifacts:
23 | path: '**/*.nupkg'
24 |
25 | deploy:
26 | - provider: NuGet
27 | server: https://www.myget.org/F/channels/api/v2/package
28 | api_key:
29 | secure: OvE2o5re489/Dr0nt3p9UzpcIcLhSt7FoHyvRUuniUbj5Wkx9+i9fBYuwmDGtxnw
30 | skip_symbols: true
31 | on:
32 | branch: master
33 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/RegisteredIO.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
5 | {
6 | public sealed class RegisteredIO
7 | {
8 | public RioRegisterBuffer RioRegisterBuffer;
9 |
10 | public RioCreateCompletionQueue RioCreateCompletionQueue;
11 | public RioCreateRequestQueue RioCreateRequestQueue;
12 |
13 |
14 | public RioReceive RioReceive;
15 | public RioSend Send;
16 |
17 | public RioNotify Notify;
18 |
19 | public RioCloseCompletionQueue CloseCompletionQueue;
20 | public RioDequeueCompletion DequeueCompletion;
21 | public RioDeregisterBuffer DeregisterBuffer;
22 | public RioResizeCompletionQueue ResizeCompletionQueue;
23 | public RioResizeRequestQueue ResizeRequestQueue;
24 |
25 |
26 | public const long CachedValue = long.MinValue;
27 |
28 | public RegisteredIO()
29 | {
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Internal/Winsock/Version.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Channels.Networking.Windows.RIO.Internal.Winsock
5 | {
6 | public struct Version
7 | {
8 | public ushort Raw;
9 |
10 | public Version(byte major, byte minor)
11 | {
12 | Raw = major;
13 | Raw <<= 8;
14 | Raw += minor;
15 | }
16 |
17 | public byte Major
18 | {
19 | get
20 | {
21 | ushort result = Raw;
22 | result >>= 8;
23 | return (byte)result;
24 | }
25 | }
26 |
27 | public byte Minor
28 | {
29 | get
30 | {
31 | ushort result = Raw;
32 | result &= 0x00FF;
33 | return (byte)result;
34 | }
35 | }
36 |
37 | public override string ToString()
38 | {
39 | return string.Format("{0}.{1}", Major, Minor);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/test/Channels.Tests/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "buildOptions": {
3 | "warningsAsErrors": true,
4 | "keyFile": "../../tools/Key.snk",
5 | "allowUnsafe": true
6 | },
7 | "dependencies": {
8 | "dotnet-test-xunit": "2.2.0-preview2-build1029",
9 | "Channels": {
10 | "target": "project"
11 | },
12 | "Channels.Text.Primitives": {
13 | "target": "project"
14 | },
15 | "Channels.Networking.Sockets": {
16 | "target": "project"
17 | },
18 | "Channels.Networking.Libuv": {
19 | "target": "project"
20 | },
21 | "Channels.Networking.Windows.RIO": {
22 | "target": "project"
23 | },
24 | "xunit": "2.2.0-beta2-build3300",
25 | "System.Collections.Sequences": "0.1.0-*"
26 | },
27 | "frameworks": {
28 | "netcoreapp1.0": {
29 | "dependencies": {
30 | "Microsoft.NETCore.App": {
31 | "version": "1.0.0-*",
32 | "type": "platform"
33 | },
34 | "Microsoft.CodeCoverage": {
35 | "type": "build",
36 | "version": "1.0.1"
37 | }
38 | },
39 | "imports": "dnxcore50"
40 | }
41 | },
42 | "testRunner": "xunit"
43 | }
--------------------------------------------------------------------------------
/src/Channels/Channels.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 |
10 | d6b28fc7-8d6d-4e9e-962f-9505d7c0e958
11 | Channels
12 | .\obj
13 | .\bin\
14 | v4.5.2
15 |
16 |
17 |
18 | 2.0
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Channels.File/Channels.File.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 |
10 | 8de69699-bae7-4186-b452-27923928a0b1
11 | Channels.File
12 | .\obj
13 | .\bin\
14 | v4.6.2
15 |
16 |
17 |
18 | 2.0
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/samples/Channels.Samples/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0-*",
3 | "buildOptions": {
4 | "allowUnsafe": true,
5 | "emitEntryPoint": true
6 | },
7 |
8 | "dependencies": {
9 | "Channels": {
10 | "target": "project"
11 | },
12 | "Channels.Text.Primitives": {
13 | "target": "project"
14 | },
15 | "Channels.Networking.Libuv": {
16 | "target": "project"
17 | },
18 | "Channels.Networking.Windows.RIO": {
19 | "target": "project"
20 | },
21 | "Channels.File": {
22 | "target": "project"
23 | },
24 | "Channels.Compression": {
25 | "target": "project"
26 | },
27 | "Newtonsoft.Json": "9.0.1",
28 | "System.Buffers": "4.0.0",
29 | "System.Slices": "0.1.0-*",
30 | "System.Text.Primitives": "0.1.0-*",
31 | "System.Text.Formatting": "0.1.0-*",
32 | "System.Text.Utf8": "0.1.0-*",
33 | "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
34 | "Microsoft.NETCore.App": {
35 | "type": "platform",
36 | "version": "1.0.0"
37 | }
38 | },
39 |
40 | "frameworks": {
41 | "netcoreapp1.0": { }
42 | },
43 |
44 | "runtimeOptions": {
45 | "configProperties": {
46 | "System.GC.Server": true
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/samples/Channels.Samples/Channels.Samples.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 |
10 | 3dcb0f92-51ae-493e-a1b6-5b42449ea2bd
11 | Channels.Samples
12 | .\obj
13 | .\bin\
14 | v4.5.2
15 |
16 |
17 |
18 | 2.0
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Channels.Compression/Channels.Compression.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 |
10 | 4fd538a6-423f-4554-af10-427a959ca9d3
11 | Channels.Compression
12 | .\obj
13 | .\bin\
14 | v4.6.2
15 |
16 |
17 |
18 | 2.0
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Sockets/Channels.Networking.Sockets.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 | 1932e4b5-a40e-4eef-ad8f-012dc01f5e5f
10 | Channels.Networking.Sockets
11 | .\obj
12 | .\bin\
13 | v4.5.2
14 |
15 |
16 | 2.0
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Channels.Text.Primitives/Channels.Text.Primitives.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 |
10 | a98068ae-c895-4b1f-adcb-60c70c64f118
11 | Channels.Text.Primitives
12 | .\obj
13 | .\bin\
14 | v4.5.2
15 |
16 |
17 |
18 | 2.0
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Channels.Networking.Libuv.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 |
10 | 11d6b886-a303-4d13-bca8-a917d5740fb6
11 | Channels.Networking.Libuv
12 | .\obj
13 | .\bin\
14 | v4.5.2
15 |
16 |
17 |
18 | 2.0
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Windows.RIO/Channels.Networking.Windows.RIO.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 |
10 | 86a0b10d-8c7a-4b20-a033-d6f679454e30
11 | Channels.Networking.Windows.RIO
12 | .\obj
13 | .\bin\
14 | v4.5.2
15 |
16 |
17 |
18 | 2.0
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Channels/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("Channels")]
11 | [assembly: AssemblyTrademark("")]
12 |
13 | // Setting ComVisible to false makes the types in this assembly not visible
14 | // to COM components. If you need to access a type in this assembly from
15 | // COM, set the ComVisible attribute to true on that type.
16 | [assembly: ComVisible(false)]
17 |
18 | // The following GUID is for the ID of the typelib if this project is exposed to COM
19 | [assembly: Guid("d6b28fc7-8d6d-4e9e-962f-9505d7c0e958")]
20 |
21 | [assembly: InternalsVisibleTo("Channels.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F33A29044FA9D740C9B3213A93E57C84B472C84E0B8A0E1AE48E67A9F8F6DE9D5F7F3D52AC23E48AC51801F1DC950ABE901DA34D2A9E3BAADB141A17C77EF3C565DD5EE5054B91CF63BB3C6AB83F72AB3AAFE93D0FC3C2348B764FAFB0B1C0733DE51459AEAB46580384BF9D74C4E28164B7CDE247F891BA07891C9D872AD2BB")]
--------------------------------------------------------------------------------
/test/Channels.Tests.Performance/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "buildOptions": {
3 | "warningsAsErrors": true,
4 | "keyFile": "../../tools/Key.snk",
5 | "allowUnsafe": true,
6 | "emitEntryPoint": true,
7 | "copyToOutput": "random.json.gz"
8 | },
9 |
10 | "publishOptions": {
11 | "includeFiles": [ "random.json.gz" ]
12 | },
13 |
14 | "dependencies": {
15 | "Channels": {
16 | "target": "project"
17 | },
18 | "Channels.Text.Primitives": {
19 | "target": "project"
20 | },
21 | "Channels.Networking.Sockets": {
22 | "target": "project"
23 | },
24 | "Channels.Networking.Libuv": {
25 | "target": "project"
26 | },
27 | "Channels.Networking.Windows.RIO": {
28 | "target": "project"
29 | },
30 | "Channels.File": {
31 | "target": "project"
32 | },
33 | "Channels.Compression": {
34 | "target": "project"
35 | },
36 | "Newtonsoft.Json": "9.0.1",
37 | "System.Text.Json": "0.1.0-*"
38 | },
39 | "frameworks": {
40 | "net46": {
41 | "imports": "dotnet",
42 | "dependencies": {
43 | "BenchmarkDotNet": "0.9.9",
44 | "BenchmarkDotNet.Diagnostics.Windows": "0.9.9"
45 | }
46 | }
47 | },
48 |
49 | "contentExclude": [ "BenchmarkDotNet.Artifacts**" ]
50 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Sockets/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("Channels.Networking.Sockets")]
11 | [assembly: AssemblyTrademark("")]
12 |
13 | // Setting ComVisible to false makes the types in this assembly not visible
14 | // to COM components. If you need to access a type in this assembly from
15 | // COM, set the ComVisible attribute to true on that type.
16 | [assembly: ComVisible(false)]
17 |
18 | // The following GUID is for the ID of the typelib if this project is exposed to COM
19 | [assembly: Guid("1932e4b5-a40e-4eef-ad8f-012dc01f5e5f")]
20 |
21 | [assembly: InternalsVisibleTo("Channels.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F33A29044FA9D740C9B3213A93E57C84B472C84E0B8A0E1AE48E67A9F8F6DE9D5F7F3D52AC23E48AC51801F1DC950ABE901DA34D2A9E3BAADB141A17C77EF3C565DD5EE5054B91CF63BB3C6AB83F72AB3AAFE93D0FC3C2348B764FAFB0B1C0733DE51459AEAB46580384BF9D74C4E28164B7CDE247F891BA07891C9D872AD2BB")]
--------------------------------------------------------------------------------
/test/Channels.Tests/Channels.Tests.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 | b9967782-565b-4b0b-97b9-043e35022674
10 | Channels.Tests
11 | .\obj
12 | .\bin\
13 | v4.5.2
14 |
15 |
16 | 2.0
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/test/Channels.Tests.Performance/Channels.Tests.Performance.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 | fd7d92ee-542c-424b-b66a-9ac2a214ec90
10 | Channels.Tests.Performance
11 | .\obj
12 | .\bin\
13 | v4.6.2
14 |
15 |
16 | 2.0
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Channels/IWritableChannel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace Channels
5 | {
6 | ///
7 | /// Defines a class that provides a channel to which data can be written.
8 | ///
9 | public interface IWritableChannel
10 | {
11 | ///
12 | /// Gets a task that completes when no more data will be read from the channel.
13 | ///
14 | ///
15 | /// This task indicates the consumer has completed and will not read anymore data.
16 | /// When this task is triggered, the producer should stop producing data.
17 | ///
18 | Task Writing { get; }
19 |
20 | ///
21 | /// Allocates memory from the channel to write into.
22 | ///
23 | /// The minimum size buffer to allocate
24 | /// A that can be written to.
25 | WritableBuffer Alloc(int minimumSize = 0);
26 |
27 | ///
28 | /// Marks the channel as being complete, meaning no more items will be written to it.
29 | ///
30 | /// Optional Exception indicating a failure that's causing the channel to complete.
31 | void Complete(Exception exception = null);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Interop/UvLoopHandle.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Threading;
6 |
7 | namespace Channels.Networking.Libuv.Interop
8 | {
9 | public class UvLoopHandle : UvMemory
10 | {
11 | public UvLoopHandle() : base()
12 | {
13 | }
14 |
15 | public void Init(Uv uv)
16 | {
17 | CreateMemory(
18 | uv,
19 | Thread.CurrentThread.ManagedThreadId,
20 | uv.loop_size());
21 |
22 | _uv.loop_init(this);
23 | }
24 |
25 | public void Run(int mode = 0)
26 | {
27 | _uv.run(this, mode);
28 | }
29 |
30 | public void Stop()
31 | {
32 | _uv.stop(this);
33 | }
34 |
35 | unsafe protected override bool ReleaseHandle()
36 | {
37 | var memory = handle;
38 | if (memory != IntPtr.Zero)
39 | {
40 | // loop_close clears the gcHandlePtr
41 | var gcHandlePtr = *(IntPtr*)memory;
42 |
43 | _uv.loop_close(this);
44 | handle = IntPtr.Zero;
45 |
46 | DestroyMemory(memory, gcHandlePtr);
47 | }
48 |
49 | return true;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Sockets/Internal/SocketExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Sockets;
2 |
3 | namespace Channels.Networking.Sockets.Internal
4 | {
5 | internal static class SocketExtensions
6 | {
7 | ///
8 | /// Note that this presumes that args.UserToken is already a Signal, and that args.Completed
9 | /// knows to call .Set on the Signal
10 | ///
11 | public static Signal ReceiveSignalAsync(this Socket socket, SocketAsyncEventArgs args)
12 | {
13 | var signal = (Signal)args.UserToken;
14 | signal.Reset();
15 | if (!socket.ReceiveAsync(args))
16 | { // mark it as already complete (probably an error)
17 | signal.Set();
18 | }
19 | return signal;
20 | }
21 |
22 | ///
23 | /// Note that this presumes that args.UserToken is already a Signal, and that args.Completed
24 | /// knows to call .Set on the Signal
25 | ///
26 | public static Signal SendSignalAsync(this Socket socket, SocketAsyncEventArgs args)
27 | {
28 | var signal = (Signal)args.UserToken;
29 | signal.Reset();
30 | if (!socket.SendAsync(args))
31 | { // mark it as already complete (probably an error)
32 | signal.Set();
33 | }
34 | return signal;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": ".NET Core Launch (web)",
6 | "type": "coreclr",
7 | "request": "launch",
8 | "preLaunchTask": "build",
9 | "program": "${workspaceRoot}/samples/Channels.Samples/bin/Debug/netcoreapp1.0/Channels.Samples.dll",
10 | "args": [],
11 | "cwd": "${workspaceRoot}",
12 | "stopAtEntry": false,
13 | "internalConsoleOptions": "openOnSessionStart",
14 | "launchBrowser": {
15 | "enabled": true,
16 | "args": "${auto-detect-url}",
17 | "windows": {
18 | "command": "cmd.exe",
19 | "args": "/C start ${auto-detect-url}"
20 | },
21 | "osx": {
22 | "command": "open"
23 | },
24 | "linux": {
25 | "command": "xdg-open"
26 | }
27 | },
28 | "env": {
29 | "ASPNETCORE_ENVIRONMENT": "Development"
30 | },
31 | "sourceFileMap": {
32 | "/Views": "${workspaceRoot}/Views"
33 | }
34 | },
35 | {
36 | "name": ".NET Core Attach",
37 | "type": "coreclr",
38 | "request": "attach",
39 | "processId": "${command.pickProcess}"
40 | }
41 | ]
42 | }
--------------------------------------------------------------------------------
/src/Channels/WritableChannel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace Channels
5 | {
6 | public abstract class WritableChannel : IWritableChannel
7 | {
8 | private readonly Channel _channel;
9 |
10 | public WritableChannel(IBufferPool pool)
11 | {
12 | _channel = new Channel(pool);
13 |
14 | Consume(_channel);
15 | }
16 |
17 | protected abstract Task WriteAsync(ReadableBuffer buffer);
18 |
19 | public Task Writing => _channel.Writing;
20 |
21 | public WritableBuffer Alloc(int minimumSize = 0) => _channel.Alloc(minimumSize);
22 |
23 | public void Complete(Exception exception = null) => _channel.CompleteWriter(exception);
24 |
25 | private async void Consume(IReadableChannel channel)
26 | {
27 | while (true)
28 | {
29 | var result = await channel.ReadAsync();
30 | var buffer = result.Buffer;
31 |
32 | try
33 | {
34 | if (buffer.IsEmpty && result.IsCompleted)
35 | {
36 | break;
37 | }
38 |
39 | await WriteAsync(buffer);
40 | }
41 | finally
42 | {
43 | channel.Advance(buffer.End);
44 | }
45 | }
46 |
47 | channel.Complete();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Channels/PreservedBuffer.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 |
6 | namespace Channels
7 | {
8 | ///
9 | /// Represents a buffer that can read a sequential series of bytes.
10 | ///
11 | public struct PreservedBuffer : IDisposable
12 | {
13 | private ReadableBuffer _buffer;
14 |
15 | internal PreservedBuffer(ref ReadableBuffer buffer)
16 | {
17 | _buffer = buffer;
18 | }
19 |
20 | ///
21 | /// Returns the preserved .
22 | ///
23 | public ReadableBuffer Buffer => _buffer;
24 |
25 | ///
26 | /// Dispose the preserved buffer.
27 | ///
28 | public void Dispose()
29 | {
30 | var returnStart = _buffer.Start.Segment;
31 | var returnEnd = _buffer.End.Segment;
32 |
33 | while (true)
34 | {
35 | var returnSegment = returnStart;
36 | returnStart = returnStart?.Next;
37 | returnSegment?.Dispose();
38 |
39 | if (returnSegment == returnEnd)
40 | {
41 | break;
42 | }
43 | }
44 |
45 | _buffer.ClearCursors();
46 | }
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: generic
2 |
3 | addons:
4 | apt:
5 | packages:
6 | - gettext
7 | - libcurl4-openssl-dev
8 | - libicu-dev
9 | - libssl-dev
10 | - libunwind8
11 | - zlib1g
12 |
13 | env:
14 | global:
15 | - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
16 | - DOTNET_CLI_TELEMETRY_OPTOUT: 1
17 |
18 | matrix:
19 | include:
20 | - os: linux
21 | dist: trusty
22 | sudo: required
23 | - os: osx
24 | osx_image: xcode7.2
25 |
26 | before_install:
27 | # Install OpenSSL
28 | - if test "$TRAVIS_OS_NAME" == "osx"; then
29 | brew install openssl;
30 | brew link --force openssl;
31 | export DOTNET_SDK_URL="https://go.microsoft.com/fwlink/?LinkID=809128";
32 | else
33 | export DOTNET_SDK_URL="https://go.microsoft.com/fwlink/?LinkID=809129";
34 | fi
35 |
36 | - export DOTNET_INSTALL_DIR="$PWD/.dotnetcli"
37 |
38 | # Install .NET CLI
39 | - mkdir $DOTNET_INSTALL_DIR
40 | - curl -L $DOTNET_SDK_URL -o dotnet_package
41 | - tar -xvzf dotnet_package -C $DOTNET_INSTALL_DIR
42 |
43 | # Add dotnet to PATH
44 | - export PATH="$DOTNET_INSTALL_DIR:$PATH"
45 |
46 | install:
47 | # Display dotnet version info
48 | - which dotnet;
49 | if [ $? -eq 0 ]; then
50 | echo "Using dotnet:";
51 | dotnet --info;
52 | else
53 | echo "dotnet.exe not found"
54 | exit 1;
55 | fi
56 |
57 | # Restore dependencies
58 | - dotnet restore
59 |
60 | script:
61 | # Build sample
62 | - dotnet build samples/Channels.Samples
63 | - dotnet test test/Channels.Tests
64 |
--------------------------------------------------------------------------------
/src/Channels/IReadableChannel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Channels
4 | {
5 | ///
6 | /// Defines a class that provides a channel from which data can be read.
7 | ///
8 | public interface IReadableChannel
9 | {
10 | ///
11 | /// Asynchronously reads a sequence of bytes from the current .
12 | ///
13 | /// A representing the asynchronous read operation.
14 | ReadableChannelAwaitable ReadAsync();
15 |
16 | ///
17 | /// Moves forward the channel's read cursor to after the consumed data.
18 | ///
19 | /// Marks the extent of the data that has been succesfully proceesed.
20 | /// Marks the extent of the data that has been read and examined.
21 | ///
22 | /// The memory for the consumed data will be released and no longer available.
23 | /// The examined data communicates to the channel when it should signal more data is available.
24 | ///
25 | void Advance(ReadCursor consumed, ReadCursor examined);
26 |
27 | ///
28 | /// Signal to the producer that the consumer is done reading.
29 | ///
30 | /// Optional Exception indicating a failure that's causing the channel to complete.
31 | void Complete(Exception exception = null);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/samples/Channels.Samples/CompressionSample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.IO.Compression;
4 | using Channels.Compression;
5 | using Channels.File;
6 |
7 | namespace Channels.Samples
8 | {
9 | public class CompressionSample
10 | {
11 | public static void Run()
12 | {
13 | using (var cf = new ChannelFactory())
14 | {
15 | var filePath = Path.GetFullPath("Program.cs");
16 |
17 | // This is what Stream looks like
18 | //var fs = File.OpenRead(filePath);
19 | //var compressed = new MemoryStream();
20 | //var compressStream = new DeflateStream(compressed, CompressionMode.Compress);
21 | //fs.CopyTo(compressStream);
22 | //compressStream.Flush();
23 | //compressed.Seek(0, SeekOrigin.Begin);
24 | // var input = channelFactory.MakeReadableChannel(compressed);
25 |
26 | var input = cf.ReadFile(filePath)
27 | .DeflateCompress(cf, CompressionLevel.Optimal)
28 | .DeflateDecompress(cf);
29 |
30 | // Wrap the console in a writable channel
31 | var output = cf.MakeWriteableChannel(Console.OpenStandardOutput());
32 |
33 | // Copy from the file channel to the console channel
34 | input.CopyToAsync(output).GetAwaiter().GetResult();
35 |
36 | input.Complete();
37 |
38 | output.Complete();
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Interop/UvShutdownReq.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 |
6 | namespace Channels.Networking.Libuv.Interop
7 | {
8 | ///
9 | /// Summary description for UvShutdownRequest
10 | ///
11 | public class UvShutdownReq : UvRequest
12 | {
13 | private readonly static Uv.uv_shutdown_cb _uv_shutdown_cb = UvShutdownCb;
14 |
15 | private Action _callback;
16 | private object _state;
17 |
18 | public UvShutdownReq() : base ()
19 | {
20 | }
21 |
22 | public void Init(UvLoopHandle loop)
23 | {
24 | CreateMemory(
25 | loop.Libuv,
26 | loop.ThreadId,
27 | loop.Libuv.req_size(Uv.RequestType.SHUTDOWN));
28 | }
29 |
30 | public void Shutdown(UvStreamHandle handle, Action callback, object state)
31 | {
32 | _callback = callback;
33 | _state = state;
34 | Pin();
35 | _uv.shutdown(this, handle, _uv_shutdown_cb);
36 | }
37 |
38 | private static void UvShutdownCb(IntPtr ptr, int status)
39 | {
40 | var req = FromIntPtr(ptr);
41 | req.Unpin();
42 | req._callback(req, status, req._state);
43 | req._callback = null;
44 | req._state = null;
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Channels.Text.Primitives/WritableChannelFormatter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Text.Formatting;
6 | using System.Text;
7 |
8 | namespace Channels.Text.Primitives
9 | {
10 | public class WritableChannelFormatter : ITextOutput
11 | {
12 | private readonly IWritableChannel _channel;
13 | private WritableBuffer _writableBuffer;
14 | private bool _needAlloc = true;
15 |
16 | public WritableChannelFormatter(IWritableChannel channel, EncodingData encoding)
17 | {
18 | _channel = channel;
19 | Encoding = encoding;
20 | }
21 |
22 | public EncodingData Encoding { get; }
23 |
24 | public Span Buffer
25 | {
26 | get
27 | {
28 | EnsureBuffer();
29 |
30 | return _writableBuffer.Memory.Span;
31 | }
32 | }
33 |
34 | public void Advance(int bytes)
35 | {
36 | _writableBuffer.Advance(bytes);
37 | }
38 |
39 | public void Enlarge(int desiredFreeBytesHint = 0)
40 | {
41 | _writableBuffer.Ensure(desiredFreeBytesHint == 0 ? 2048 : desiredFreeBytesHint);
42 | }
43 |
44 | public void Write(Span data)
45 | {
46 | EnsureBuffer();
47 | _writableBuffer.Write(data);
48 | }
49 |
50 | public async Task FlushAsync()
51 | {
52 | await _writableBuffer.FlushAsync();
53 | _needAlloc = true;
54 | }
55 |
56 | private void EnsureBuffer()
57 | {
58 | if (_needAlloc)
59 | {
60 | _writableBuffer = _channel.Alloc();
61 | _needAlloc = false;
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Channels.Text.Primitives/SplitEnumerable.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Channels.Text.Primitives
5 | {
6 | ///
7 | /// Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
8 | ///
9 | public struct SplitEnumerable : IEnumerable
10 | {
11 | private ReadableBuffer _buffer;
12 |
13 | private int _count;
14 |
15 | private byte _delimiter;
16 |
17 | internal SplitEnumerable(ReadableBuffer buffer, byte delimiter)
18 | {
19 | _buffer = buffer;
20 | _delimiter = delimiter;
21 | _count = buffer.IsEmpty ? 0 : -1;
22 | }
23 |
24 | ///
25 | /// Count the number of elemnts in this sequence
26 | ///
27 | public int Count()
28 | {
29 | if (_count >= 0)
30 | {
31 | return _count;
32 | }
33 |
34 | int count = 1;
35 | var current = _buffer;
36 | ReadableBuffer ignore;
37 | ReadCursor cursor;
38 | while (current.TrySliceTo(_delimiter, out ignore, out cursor))
39 | {
40 | current = current.Slice(cursor).Slice(1);
41 | count++;
42 | }
43 | return _count = count;
44 | }
45 | ///
46 | /// Returns an enumerator that iterates through the collection.
47 | ///
48 | public SplitEnumerator GetEnumerator()
49 | => new SplitEnumerator(_buffer, _delimiter);
50 |
51 | IEnumerator IEnumerable.GetEnumerator()
52 | => GetEnumerator();
53 |
54 | IEnumerator IEnumerable.GetEnumerator()
55 | => GetEnumerator();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/samples/Channels.Samples/AspNetHttpServerSample.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Channels.Samples.Http;
3 | using Microsoft.AspNetCore.Builder;
4 | using Microsoft.AspNetCore.Hosting;
5 |
6 | namespace Channels.Samples
7 | {
8 | public class AspNetHttpServerSample
9 | {
10 | private static readonly UTF8Encoding _utf8Encoding = new UTF8Encoding(false);
11 | private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
12 |
13 | public static void Run()
14 | {
15 | using (var httpServer = new HttpServer())
16 | {
17 | var host = new WebHostBuilder()
18 | .UseUrls("http://*:5000")
19 | .UseServer(httpServer)
20 | // .UseKestrel()
21 | .Configure(app =>
22 | {
23 | app.Run(context =>
24 | {
25 | context.Response.StatusCode = 200;
26 | context.Response.ContentType = "text/plain";
27 | // HACK: Setting the Content-Length header manually avoids the cost of serializing the int to a string.
28 | // This is instead of: httpContext.Response.ContentLength = _helloWorldPayload.Length;
29 | context.Response.Headers["Content-Length"] = "13";
30 | return context.Response.Body.WriteAsync(_helloWorldPayload, 0, _helloWorldPayload.Length);
31 | });
32 | })
33 | .Build();
34 | host.Run();
35 | }
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/Internal/WriteReqPool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Channels.Networking.Libuv.Interop;
4 |
5 | namespace Channels.Networking.Libuv.Internal
6 | {
7 | public class WriteReqPool
8 | {
9 | private const int _maxPooledWriteReqs = 1024;
10 |
11 | private readonly UvThread _thread;
12 | private readonly Queue _pool = new Queue(_maxPooledWriteReqs);
13 | private bool _disposed;
14 |
15 | public WriteReqPool(UvThread thread)
16 | {
17 | _thread = thread;
18 | }
19 |
20 | public UvWriteReq Allocate()
21 | {
22 | if (_disposed)
23 | {
24 | throw new ObjectDisposedException(GetType().Name);
25 | }
26 |
27 | UvWriteReq req;
28 | if (_pool.Count > 0)
29 | {
30 | req = _pool.Dequeue();
31 | }
32 | else
33 | {
34 | req = new UvWriteReq();
35 | req.Init(_thread.Loop);
36 | }
37 |
38 | return req;
39 | }
40 |
41 | public void Return(UvWriteReq req)
42 | {
43 | if (_disposed)
44 | {
45 | throw new ObjectDisposedException(GetType().Name);
46 | }
47 |
48 | if (_pool.Count < _maxPooledWriteReqs)
49 | {
50 | _pool.Enqueue(req);
51 | }
52 | else
53 | {
54 | req.Dispose();
55 | }
56 | }
57 |
58 | public void Dispose()
59 | {
60 | if (!_disposed)
61 | {
62 | _disposed = true;
63 |
64 | while (_pool.Count > 0)
65 | {
66 | _pool.Dequeue().Dispose();
67 | }
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/test/Channels.Tests.Performance/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using BenchmarkDotNet.Configs;
3 | using BenchmarkDotNet.Diagnostics.Windows;
4 | using BenchmarkDotNet.Jobs;
5 | using BenchmarkDotNet.Running;
6 |
7 | namespace Channels.Tests.Performance
8 | {
9 | public class Program
10 | {
11 | public static void Main(string[] args)
12 | {
13 | var options = (uint[])Enum.GetValues(typeof(BenchmarkType));
14 | BenchmarkType type;
15 | if (args.Length != 1 || !Enum.TryParse(args[0], out type))
16 | {
17 | Console.WriteLine($"Please add benchmark to run as parameter:");
18 | for (var i = 0; i < options.Length; i++)
19 | {
20 | Console.WriteLine($" {((BenchmarkType)options[i]).ToString()}" );
21 | }
22 |
23 | return;
24 | }
25 |
26 | RunSelectedBenchmarks(type);
27 | }
28 |
29 | private static void RunSelectedBenchmarks(BenchmarkType type)
30 | {
31 | if (type.HasFlag(BenchmarkType.Streams))
32 | {
33 | BenchmarkRunner.Run();
34 | }
35 | }
36 | }
37 |
38 | [Flags]
39 | public enum BenchmarkType : uint
40 | {
41 | Streams = 1,
42 | // add new ones in powers of two - e.g. 2,4,8,16...
43 |
44 | All = uint.MaxValue
45 | }
46 |
47 | public class DefaultConfig : ManualConfig
48 | {
49 | public DefaultConfig()
50 | {
51 | Add(Job.Default.
52 | With(Platform.X64).
53 | With(Jit.RyuJit).
54 | With(Runtime.Clr).
55 | WithLaunchCount(3).
56 | WithIterationTime(200). // 200ms per iteration
57 | WithWarmupCount(5).
58 | WithTargetCount(10));
59 |
60 | Add(new MemoryDiagnoser());
61 | }
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/test/Channels.Tests/BufferPoolFacts.cs:
--------------------------------------------------------------------------------
1 | using Channels.Networking.Sockets.Internal;
2 | using System;
3 | using Xunit;
4 |
5 | namespace Channels.Tests
6 | {
7 | public class BufferPoolFacts
8 | {
9 | [Fact]
10 | public void BufferPoolBasicUsage()
11 | {
12 | var pool = new MicroBufferPool(8, 4);
13 |
14 | ArraySegment[] segments = new ArraySegment[5];
15 |
16 | Assert.Equal(0, pool.InUse);
17 | Assert.Equal(4, pool.Available);
18 | Assert.True(pool.TryTake(out segments[0]));
19 | Assert.True(pool.TryTake(out segments[1]));
20 | Assert.Equal(2, pool.InUse);
21 | Assert.Equal(2, pool.Available);
22 | Assert.True(pool.TryTake(out segments[2]));
23 | Assert.True(pool.TryTake(out segments[3]));
24 | Assert.False(pool.TryTake(out segments[4]));
25 | Assert.Equal(4, pool.InUse);
26 | Assert.Equal(0, pool.Available);
27 | for (int i = 0; i < 4; i++)
28 | {
29 | Assert.Equal(i * 8, segments[i].Offset);
30 | Assert.Equal(8, segments[i].Count);
31 | }
32 |
33 | pool.Recycle(segments[3]);
34 | pool.Recycle(segments[1]);
35 | Assert.Equal(2, pool.InUse);
36 | Assert.Equal(2, pool.Available);
37 | Assert.True(pool.TryTake(out segments[1]));
38 | Assert.True(pool.TryTake(out segments[3]));
39 | Assert.False(pool.TryTake(out segments[4]));
40 | Assert.Equal(4, pool.InUse);
41 | Assert.Equal(0, pool.Available);
42 |
43 | Assert.Equal(24, segments[1].Offset);
44 | Assert.Equal(8, segments[3].Offset);
45 | for(int i = 0; i < 4; i++)
46 | {
47 | pool.Recycle(segments[i]);
48 | }
49 | Assert.Equal(0, pool.InUse);
50 | Assert.Equal(4, pool.Available);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Channels.Networking.Libuv/UvTcpClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Threading.Tasks;
4 | using Channels.Networking.Libuv.Interop;
5 |
6 | namespace Channels.Networking.Libuv
7 | {
8 | public class UvTcpClient
9 | {
10 | private static readonly Action _connectCallback = OnConnection;
11 | private static readonly Action