NetSharp

NetSharp.git
git clone git://git.lenczewski.org/NetSharp.git
Log | Files | Refs | README | LICENSE

commit 54f507b485558a201bc314edac955c237ca93332
parent 3cc79cf19dc7cfe3311c32f61caaf1275d064008
Author: Mikolaj Lenczewski <mikolaj.lenczewski308@gmail.com>
Date:   Sat, 25 Apr 2020 21:11:45 +0100

Rolled back broken Cancellation support. Will implement when i figure out how to do it properly.

Diffstat:
MNetSharp/NetSharp/NetSharp.xml | 97+++++--------------------------------------------------------------------------
MNetSharp/NetSharp/Sockets/Datagram/DatagramSocketClient.cs | 18++----------------
MNetSharp/NetSharp/Sockets/SocketClient.cs | 153++-----------------------------------------------------------------------------
MNetSharp/NetSharp/Sockets/SocketConnection.cs | 3++-
MNetSharp/NetSharp/Sockets/Stream/StreamSocketClient.cs | 29+++--------------------------
MNetSharp/NetSharp/Utils/SlimObjectPool.cs | 14++++++++++++--
MNetSharp/NetSharpExamples/Program.cs | 2+-
7 files changed, 28 insertions(+), 288 deletions(-)

diff --git a/NetSharp/NetSharp/NetSharp.xml b/NetSharp/NetSharp/NetSharp.xml @@ -192,9 +192,6 @@ <member name="M:NetSharp.Sockets.Datagram.DatagramSocketClient.HandleIoCompleted(System.Object,System.Net.Sockets.SocketAsyncEventArgs)"> <inheritdoc /> </member> - <member name="M:NetSharp.Sockets.Datagram.DatagramSocketClient.ResetSocketOnAsyncCancellationEx"> - <inheritdoc /> - </member> <member name="M:NetSharp.Sockets.Datagram.DatagramSocketClient.ResetTransmissionArgs(System.Net.Sockets.SocketAsyncEventArgs)"> <inheritdoc /> </member> @@ -262,6 +259,7 @@ <summary> Abstract base class for clients. </summary> + TODO implement cancellation of ReceiveAsync and ReceiveFromAsync methods. </member> <member name="M:NetSharp.Sockets.SocketClient.#ctor(System.Net.Sockets.AddressFamily@,System.Net.Sockets.SocketType@,System.Net.Sockets.ProtocolType@,System.Int32@,System.UInt16@)"> <summary> @@ -301,54 +299,12 @@ The remote end point which to which to connect the client. </param> <param name="cancellationToken"> - The <see cref="T:System.Threading.CancellationToken" /> upon whose cancellation the connection attempt should be aborted. + The <see cref="T:System.Threading.CancellationToken" /> upon whose cancellation the connection attempt should be aborted. TODO make functional </param> <returns> A <see cref="T:System.Threading.Tasks.ValueTask" /> representing the connection attempt. </returns> </member> - <member name="T:NetSharp.Sockets.SocketClient.AsyncOperationCancellationToken"> - <summary> - A state token for cancelling asynchronous socket operations. - </summary> - </member> - <member name="F:NetSharp.Sockets.SocketClient.AsyncOperationCancellationToken.CompletionSource"> - <summary> - The completion source associated with the network IO operation. - </summary> - </member> - <member name="F:NetSharp.Sockets.SocketClient.AsyncOperationCancellationToken.Socket"> - <summary> - The socket on which the operation was started. - </summary> - </member> - <member name="F:NetSharp.Sockets.SocketClient.AsyncOperationCancellationToken.TransmissionArgs"> - <summary> - The <see cref="T:System.Net.Sockets.SocketAsyncEventArgs" /> instance associated with the socket operation. - </summary> - </member> - <member name="F:NetSharp.Sockets.SocketClient.AsyncOperationCancellationToken.TransmissionArgsPool"> - <summary> - The pool to which the <see cref="F:NetSharp.Sockets.SocketClient.AsyncOperationCancellationToken.TransmissionArgs" /> should be returned upon operation cancellation. - </summary> - </member> - <member name="M:NetSharp.Sockets.SocketClient.AsyncOperationCancellationToken.#ctor(System.Net.Sockets.Socket@,System.Net.Sockets.SocketAsyncEventArgs@,NetSharp.Utils.SlimObjectPool{System.Net.Sockets.SocketAsyncEventArgs}@,System.Threading.Tasks.TaskCompletionSource{System.Boolean}@)"> - <summary> - Constructs a new instance of the <see cref="T:NetSharp.Sockets.SocketClient.AsyncOperationCancellationToken" /> struct. - </summary> - <param name="socket"> - The socket on which the operation was started. - </param> - <param name="args"> - The socket event args associated with the operation. - </param> - <param name="argsPool"> - The pool to which the <paramref name="args" /> instance will be returned upon cancellation. - </param> - <param name="completionSource"> - The completion source associated with the operation. - </param> - </member> <member name="T:NetSharp.Sockets.SocketClient.AsyncOperationToken"> <summary> A state token for asynchronous socket operations. @@ -375,48 +331,6 @@ The cancellation token to observe during the operation. </param> </member> - <member name="T:NetSharp.Sockets.SocketClient.AsyncTransmissionCancellationToken"> - <summary> - A state token for cancelling asynchronous network IO operations. - </summary> - </member> - <member name="F:NetSharp.Sockets.SocketClient.AsyncTransmissionCancellationToken.CompletionSource"> - <summary> - The completion source associated with the network IO operation. - </summary> - </member> - <member name="F:NetSharp.Sockets.SocketClient.AsyncTransmissionCancellationToken.Socket"> - <summary> - The socket on which the operation was started. - </summary> - </member> - <member name="F:NetSharp.Sockets.SocketClient.AsyncTransmissionCancellationToken.TransmissionArgs"> - <summary> - The <see cref="T:System.Net.Sockets.SocketAsyncEventArgs" /> instance associated with the network IO operation. - </summary> - </member> - <member name="F:NetSharp.Sockets.SocketClient.AsyncTransmissionCancellationToken.TransmissionArgsPool"> - <summary> - The pool to which the <see cref="F:NetSharp.Sockets.SocketClient.AsyncTransmissionCancellationToken.TransmissionArgs" /> should be returned upon operation cancellation. - </summary> - </member> - <member name="M:NetSharp.Sockets.SocketClient.AsyncTransmissionCancellationToken.#ctor(System.Net.Sockets.Socket@,System.Net.Sockets.SocketAsyncEventArgs@,NetSharp.Utils.SlimObjectPool{System.Net.Sockets.SocketAsyncEventArgs}@,System.Threading.Tasks.TaskCompletionSource{NetSharp.Utils.TransmissionResult}@)"> - <summary> - Constructs a new instance of the <see cref="T:NetSharp.Sockets.SocketClient.AsyncTransmissionCancellationToken" /> struct. - </summary> - <param name="socket"> - The socket on which the operation was started. - </param> - <param name="args"> - The socket event args associated with the operation. - </param> - <param name="argsPool"> - The pool to which the <paramref name="args" /> instance will be returned upon cancellation. - </param> - <param name="completionSource"> - The completion source associated with the operation. - </param> - </member> <member name="T:NetSharp.Sockets.SocketClient.AsyncTransmissionToken"> <summary> A state token for asynchronous network IO operations. @@ -447,7 +361,6 @@ <summary> Abstract base class for clients and servers. </summary> - TODO implement access for socket options in conjunction to cancellable Socket.XXXAsync calls </member> <member name="F:NetSharp.Sockets.SocketConnection.BufferPool"> <summary> @@ -677,9 +590,6 @@ <member name="M:NetSharp.Sockets.Stream.StreamSocketClient.HandleIoCompleted(System.Object,System.Net.Sockets.SocketAsyncEventArgs)"> <inheritdoc /> </member> - <member name="M:NetSharp.Sockets.Stream.StreamSocketClient.ResetSocketOnAsyncCancellationEx"> - <inheritdoc /> - </member> <member name="M:NetSharp.Sockets.Stream.StreamSocketClient.ResetTransmissionArgs(System.Net.Sockets.SocketAsyncEventArgs)"> <inheritdoc /> </member> @@ -1081,6 +991,9 @@ The instance which should be reset. </param> </member> + <member name="M:NetSharp.Utils.SlimObjectPool`1.Dispose"> + <inheritdoc /> + </member> <member name="M:NetSharp.Utils.SlimObjectPool`1.Rent"> <summary> Leases a new <typeparamref name="T" /> instance from the pool, and returns it. diff --git a/NetSharp/NetSharp/Sockets/Datagram/DatagramSocketClient.cs b/NetSharp/NetSharp/Sockets/Datagram/DatagramSocketClient.cs @@ -77,8 +77,6 @@ namespace NetSharp.Sockets.Datagram case SocketError.OperationAborted: Debug.WriteLine("CompleteConnect experienced SocketError.OperationAborted!"); - connectToken.CompletionSource.SetResult(false); - break; default: @@ -107,8 +105,6 @@ namespace NetSharp.Sockets.Datagram case SocketError.OperationAborted: Debug.WriteLine("CompleteReceiveFrom experienced SocketError.OperationAborted!"); - receiveToken.CompletionSource.SetResult(TransmissionResult.Timeout); - break; default: @@ -142,8 +138,6 @@ namespace NetSharp.Sockets.Datagram case SocketError.OperationAborted: Debug.WriteLine("CompleteSendTo experienced SocketError.OperationAborted!"); - sendToken.CompletionSource.SetResult(TransmissionResult.Timeout); - break; default: @@ -206,12 +200,6 @@ namespace NetSharp.Sockets.Datagram } /// <inheritdoc /> - protected override void ResetSocketOnAsyncCancellationEx() - { - throw new NotImplementedException(); - } - - /// <inheritdoc /> protected override void ResetTransmissionArgs(SocketAsyncEventArgs args) { } @@ -237,8 +225,7 @@ namespace NetSharp.Sockets.Datagram args.UserToken = new AsyncTransmissionToken(in tcs, in cancellationToken); // TODO implement cancellation for client socket receiveFromAsync - cancellationToken.Register(CancelAsyncTransmission, - new AsyncTransmissionCancellationToken(in Connection, in args, in TransmissionArgsPool, in tcs)); + cancellationToken.Register(CancelAsyncTransmissionCallback, new object()); if (Connection.ReceiveFromAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task); @@ -270,8 +257,7 @@ namespace NetSharp.Sockets.Datagram args.UserToken = new AsyncTransmissionToken(in tcs, in cancellationToken); // TODO implement cancellation for client socket sendToAsync - cancellationToken.Register(CancelAsyncTransmission, - new AsyncTransmissionCancellationToken(in Connection, in args, in TransmissionArgsPool, in tcs)); + cancellationToken.Register(CancelAsyncTransmissionCallback, new object()); if (Connection.SendToAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task); diff --git a/NetSharp/NetSharp/Sockets/SocketClient.cs b/NetSharp/NetSharp/Sockets/SocketClient.cs @@ -12,6 +12,7 @@ namespace NetSharp.Sockets /// <summary> /// Abstract base class for clients. /// </summary> + /// TODO implement cancellation of ReceiveAsync and ReceiveFromAsync methods. public abstract class SocketClient : SocketConnection { /// <summary> @@ -38,41 +39,11 @@ namespace NetSharp.Sockets { } - private void ResetSocketOnAsyncCancellation() + protected void CancelAsyncTransmissionCallback(object tokenObj) { - // TODO actually implement cancellation of Socket.XXXAsync methods - - // backup socket options - } - - protected void CancelAsyncOperation(object tokenObj) - { - AsyncOperationCancellationToken token = (AsyncOperationCancellationToken)tokenObj; - - Debug.WriteLine("Cancelling asynchronous operation!"); - - DestroyTransmissionArgs(token.TransmissionArgs); - - // TODO consider replacing the destroyed args - - token.CompletionSource.SetResult(false); - } - - protected void CancelAsyncTransmission(object tokenObj) - { - AsyncTransmissionCancellationToken token = (AsyncTransmissionCancellationToken)tokenObj; - Debug.WriteLine("Cancelling asynchronous transmission!"); - - DestroyTransmissionArgs(token.TransmissionArgs); - - // TODO consider replacing the destroyed args - - token.CompletionSource.SetResult(TransmissionResult.Timeout); } - protected abstract void ResetSocketOnAsyncCancellationEx(); - /// <summary> /// Connects the client to the specified end point. If called on a <see cref="SocketType.Dgram" />-based client, this method configures the /// default remote host, and the client will ignore any packets not coming from this default host (i.e the given <paramref name="remoteEndPoint" />). @@ -93,7 +64,7 @@ namespace NetSharp.Sockets /// The remote end point which to which to connect the client. /// </param> /// <param name="cancellationToken"> - /// The <see cref="CancellationToken" /> upon whose cancellation the connection attempt should be aborted. + /// The <see cref="CancellationToken" /> upon whose cancellation the connection attempt should be aborted. TODO make functional /// </param> /// <returns> /// A <see cref="ValueTask" /> representing the connection attempt. @@ -107,18 +78,6 @@ namespace NetSharp.Sockets args.RemoteEndPoint = remoteEndPoint; args.UserToken = new AsyncOperationToken(in tcs, in cancellationToken); - //TODO implement cancellation for client socket connectAsync - cancellationToken.Register(token => - { - AsyncOperationCancellationToken operationCancellationToken = (AsyncOperationCancellationToken)token; - - Socket.CancelConnectAsync(operationCancellationToken.TransmissionArgs); - - operationCancellationToken.CompletionSource.SetResult(false); - - operationCancellationToken.TransmissionArgsPool.Return(operationCancellationToken.TransmissionArgs); - }, new AsyncOperationCancellationToken(in Connection, in args, in TransmissionArgsPool, in tcs)); - if (Connection.ConnectAsync(args)) return new ValueTask(tcs.Task); TransmissionArgsPool.Return(args); @@ -127,59 +86,6 @@ namespace NetSharp.Sockets } /// <summary> - /// A state token for cancelling asynchronous socket operations. - /// </summary> - protected readonly struct AsyncOperationCancellationToken - { - /// <summary> - /// The completion source associated with the network IO operation. - /// </summary> - public readonly TaskCompletionSource<bool> CompletionSource; - - /// <summary> - /// The socket on which the operation was started. - /// </summary> - public readonly Socket Socket; - - /// <summary> - /// The <see cref="SocketAsyncEventArgs" /> instance associated with the socket operation. - /// </summary> - public readonly SocketAsyncEventArgs TransmissionArgs; - - /// <summary> - /// The pool to which the <see cref="TransmissionArgs" /> should be returned upon operation cancellation. - /// </summary> - public readonly SlimObjectPool<SocketAsyncEventArgs> TransmissionArgsPool; - - /// <summary> - /// Constructs a new instance of the <see cref="AsyncOperationCancellationToken" /> struct. - /// </summary> - /// <param name="socket"> - /// The socket on which the operation was started. - /// </param> - /// <param name="args"> - /// The socket event args associated with the operation. - /// </param> - /// <param name="argsPool"> - /// The pool to which the <paramref name="args" /> instance will be returned upon cancellation. - /// </param> - /// <param name="completionSource"> - /// The completion source associated with the operation. - /// </param> - public AsyncOperationCancellationToken(in Socket socket, in SocketAsyncEventArgs args, - in SlimObjectPool<SocketAsyncEventArgs> argsPool, in TaskCompletionSource<bool> completionSource) - { - Socket = socket; - - TransmissionArgs = args; - - TransmissionArgsPool = argsPool; - - CompletionSource = completionSource; - } - } - - /// <summary> /// A state token for asynchronous socket operations. /// </summary> protected readonly struct AsyncOperationToken @@ -212,59 +118,6 @@ namespace NetSharp.Sockets } /// <summary> - /// A state token for cancelling asynchronous network IO operations. - /// </summary> - protected readonly struct AsyncTransmissionCancellationToken - { - /// <summary> - /// The completion source associated with the network IO operation. - /// </summary> - public readonly TaskCompletionSource<TransmissionResult> CompletionSource; - - /// <summary> - /// The socket on which the operation was started. - /// </summary> - public readonly Socket Socket; - - /// <summary> - /// The <see cref="SocketAsyncEventArgs" /> instance associated with the network IO operation. - /// </summary> - public readonly SocketAsyncEventArgs TransmissionArgs; - - /// <summary> - /// The pool to which the <see cref="TransmissionArgs" /> should be returned upon operation cancellation. - /// </summary> - public readonly SlimObjectPool<SocketAsyncEventArgs> TransmissionArgsPool; - - /// <summary> - /// Constructs a new instance of the <see cref="AsyncTransmissionCancellationToken" /> struct. - /// </summary> - /// <param name="socket"> - /// The socket on which the operation was started. - /// </param> - /// <param name="args"> - /// The socket event args associated with the operation. - /// </param> - /// <param name="argsPool"> - /// The pool to which the <paramref name="args" /> instance will be returned upon cancellation. - /// </param> - /// <param name="completionSource"> - /// The completion source associated with the operation. - /// </param> - public AsyncTransmissionCancellationToken(in Socket socket, in SocketAsyncEventArgs args, - in SlimObjectPool<SocketAsyncEventArgs> argsPool, in TaskCompletionSource<TransmissionResult> completionSource) - { - Socket = socket; - - TransmissionArgs = args; - - TransmissionArgsPool = argsPool; - - CompletionSource = completionSource; - } - } - - /// <summary> /// A state token for asynchronous network IO operations. /// </summary> protected readonly struct AsyncTransmissionToken diff --git a/NetSharp/NetSharp/Sockets/SocketConnection.cs b/NetSharp/NetSharp/Sockets/SocketConnection.cs @@ -10,7 +10,6 @@ namespace NetSharp.Sockets /// <summary> /// Abstract base class for clients and servers. /// </summary> - /// TODO implement access for socket options in conjunction to cancellable Socket.XXXAsync calls public abstract class SocketConnection : IDisposable { /// <summary> @@ -119,6 +118,8 @@ namespace NetSharp.Sockets Connection.Close(); Connection.Dispose(); + + TransmissionArgsPool.Dispose(); } /// <summary> diff --git a/NetSharp/NetSharp/Sockets/Stream/StreamSocketClient.cs b/NetSharp/NetSharp/Sockets/Stream/StreamSocketClient.cs @@ -283,12 +283,6 @@ namespace NetSharp.Sockets.Stream } /// <inheritdoc /> - protected override void ResetSocketOnAsyncCancellationEx() - { - throw new NotImplementedException(); - } - - /// <inheritdoc /> protected override void ResetTransmissionArgs(SocketAsyncEventArgs args) { } @@ -308,16 +302,7 @@ namespace NetSharp.Sockets.Stream args.UserToken = new AsyncOperationToken(in tcs, in cancellationToken); //TODO implement cancellation for client socket disconnectAsync - cancellationToken.Register(token => - { - AsyncOperationCancellationToken operationCancellationToken = (AsyncOperationCancellationToken)token; - - Socket.CancelConnectAsync(operationCancellationToken.TransmissionArgs); - - operationCancellationToken.CompletionSource.SetCanceled(); - - operationCancellationToken.TransmissionArgsPool.Return(operationCancellationToken.TransmissionArgs); - }, new AsyncOperationCancellationToken(in Connection, in args, in TransmissionArgsPool, in tcs)); + //cancellationToken.Register(); if (Connection.DisconnectAsync(args)) return new ValueTask(tcs.Task); @@ -352,11 +337,7 @@ namespace NetSharp.Sockets.Stream args.UserToken = new AsyncTransmissionToken(in tcs, in cancellationToken); // TODO implement cancellation for client socket receiveAsync - cancellationToken.Register(token => - { - AsyncTransmissionCancellationToken transmissionCancellationToken = - (AsyncTransmissionCancellationToken)token; - }, new AsyncTransmissionCancellationToken(in Connection, in args, in TransmissionArgsPool, in tcs)); + cancellationToken.Register(CancelAsyncTransmissionCallback, new object()); if (Connection.ReceiveAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task); @@ -393,11 +374,7 @@ namespace NetSharp.Sockets.Stream args.UserToken = new AsyncTransmissionToken(in tcs, in cancellationToken); // TODO implement cancellation for client socket sendAsync - cancellationToken.Register(token => - { - AsyncTransmissionCancellationToken transmissionCancellationToken = - (AsyncTransmissionCancellationToken)token; - }, new AsyncTransmissionCancellationToken(in Connection, in args, in TransmissionArgsPool, in tcs)); + cancellationToken.Register(CancelAsyncTransmissionCallback, new object()); if (Connection.SendAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task); diff --git a/NetSharp/NetSharp/Utils/SlimObjectPool.cs b/NetSharp/NetSharp/Utils/SlimObjectPool.cs @@ -1,4 +1,5 @@ -using System.Collections.Concurrent; +using System; +using System.Collections.Concurrent; namespace NetSharp.Utils { @@ -8,7 +9,7 @@ namespace NetSharp.Utils /// <typeparam name="T"> /// The type of item stored in the pool. /// </typeparam> - public class SlimObjectPool<T> where T : class + public class SlimObjectPool<T> : IDisposable where T : class { private readonly CanRebufferObjectPredicate canObjectBeRebufferedPredicate; @@ -110,6 +111,15 @@ namespace NetSharp.Utils /// </param> public delegate void ResetObjectDelegate(T instance); + /// <inheritdoc /> + public void Dispose() + { + foreach (T pooledObject in objectBuffer) + { + destroyObjectDelegate(pooledObject); + } + } + /// <summary> /// Leases a new <typeparamref name="T" /> instance from the pool, and returns it. /// </summary> diff --git a/NetSharp/NetSharpExamples/Program.cs b/NetSharp/NetSharpExamples/Program.cs @@ -16,7 +16,7 @@ namespace NetSharpExamples new UdpSocketClientSyncBenchmark(), new UdpSocketClientAsyncBenchmark(), new UdpSocketClientExample(), - new UdpSocketClientCancellationExample(), + //new UdpSocketClientCancellationExample(), // TODO make functional // TCP socket server and client examples new TcpSocketServerBenchmark(),