diff options
author | vnugent <public@vaughnnugent.com> | 2024-02-14 14:10:27 -0500 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2024-02-14 14:10:27 -0500 |
commit | 2b1314c1475e7e1831c691cf349cb89c66fa320c (patch) | |
tree | 091fc132a2bee2e79a68d8c6d5eb20f1d989a3d2 /lib/Net.Transport.SimpleTCP | |
parent | f4e4db7c5320976406feb252ae8f8bdbe9b3e351 (diff) |
Squashed commit of the following:
commit ddd8a651b6eb43cfdd49d84056f8b9c34b543992
Author: vnugent <public@vaughnnugent.com>
Date: Wed Feb 14 00:15:50 2024 -0500
ci: reduce output noise and update Argon2 build
commit cf942959ff2feea03d3eda2ff2a263bdac4d6bc6
Author: vnugent <public@vaughnnugent.com>
Date: Mon Feb 12 18:39:18 2024 -0500
chore: update packages and minor fixes
commit ab506af9e2de2876b11bb45b3c7e787616c80155
Author: vnugent <public@vaughnnugent.com>
Date: Fri Feb 9 21:27:24 2024 -0500
fix: patch and update core runtime service injection
commit 7ed5e8b19164c28d3a238bd56878d2161fbea2e4
Author: vnugent <public@vaughnnugent.com>
Date: Thu Feb 8 18:26:11 2024 -0500
fork dotnetplugins and make some intial updates/upgrades
commit f4cab88d67be5da0953b14bd46fc972d4acc8606
Author: vnugent <public@vaughnnugent.com>
Date: Thu Feb 8 12:16:13 2024 -0500
update some heap api functions
commit 6035bf7ed8412f1da361cc5feddd860abfaf4fc1
Author: vnugent <public@vaughnnugent.com>
Date: Wed Feb 7 22:09:11 2024 -0500
working file-watcher notifications/rework
commit 698f8edf694ad9700ee2ce2220e692b496448ff9
Author: vnugent <public@vaughnnugent.com>
Date: Wed Feb 7 20:37:28 2024 -0500
remove mem-template and add file-watcher utility
commit b17591e0fb363222fcd7d93c2bad4ab1b102385f
Author: vnugent <public@vaughnnugent.com>
Date: Wed Feb 7 18:28:21 2024 -0500
add small memmove support for known small blocks
commit 631be4d4b27fdbcd4b0526e17a128bb0d86911eb
Author: vnugent <public@vaughnnugent.com>
Date: Wed Feb 7 18:08:02 2024 -0500
setup some readonly ref arguments and convert copy apis to readonly refs
commit 2ba8dec68d5cb192e61ad0141d4b460076d3f90a
Author: vnugent <public@vaughnnugent.com>
Date: Mon Feb 5 18:30:38 2024 -0500
restructure internal memmove strategies
commit 25cf02872da980893ad7fb51d4eccc932380582b
Author: vnugent <public@vaughnnugent.com>
Date: Sun Feb 4 01:29:18 2024 -0500
add http stream interface, profiling -> file read updates
commit 757668c44e78864dc69d5713a2cfba6db2ed9a2a
Author: vnugent <public@vaughnnugent.com>
Date: Fri Feb 2 14:27:04 2024 -0500
streamline data-copy api with proper large block support and net8 feature updates
commit f22c1765fd72ab40a10d8ec92a8cb6d9ec1b1a04
Author: vnugent <public@vaughnnugent.com>
Date: Mon Jan 29 16:16:23 2024 -0500
check for compression lib updates to close #2 and fix some ci build stuff
commit f974bfdef6a795b4a1c04602502ef506ef2587a9
Author: vnugent <public@vaughnnugent.com>
Date: Tue Jan 23 17:36:17 2024 -0500
switch allocator libs to lgpl2.1
commit 1fe5e01b329cd27b675000f1a557b784d3c88b56
Author: vnugent <public@vaughnnugent.com>
Date: Tue Jan 23 17:05:59 2024 -0500
consolidate allocator packages and close #1
commit 74e1107e522f00b670526193396217f40a6bade7
Author: vnugent <public@vaughnnugent.com>
Date: Tue Jan 23 15:43:40 2024 -0500
cache extension api tweaks
commit 96ca2b0388a6326b9bb74f3ab2f62eaede6681e0
Author: vnugent <public@vaughnnugent.com>
Date: Mon Jan 22 17:54:23 2024 -0500
explicit tcp server args reuse
Diffstat (limited to 'lib/Net.Transport.SimpleTCP')
-rw-r--r-- | lib/Net.Transport.SimpleTCP/src/AwaitableAsyncServerSocket.cs | 27 | ||||
-rw-r--r-- | lib/Net.Transport.SimpleTCP/src/SocketPipeLineWorker.cs | 18 | ||||
-rw-r--r-- | lib/Net.Transport.SimpleTCP/src/TcpServer.cs | 22 |
3 files changed, 50 insertions, 17 deletions
diff --git a/lib/Net.Transport.SimpleTCP/src/AwaitableAsyncServerSocket.cs b/lib/Net.Transport.SimpleTCP/src/AwaitableAsyncServerSocket.cs index e287d64..e830107 100644 --- a/lib/Net.Transport.SimpleTCP/src/AwaitableAsyncServerSocket.cs +++ b/lib/Net.Transport.SimpleTCP/src/AwaitableAsyncServerSocket.cs @@ -83,7 +83,10 @@ namespace VNLib.Net.Transport.Tcp //Begin the accept SocketError error = await _allArgs.AcceptAsync(serverSocket); - if(error == SocketError.Success) + //Clear the buffer reference + _allArgs.SetBuffer(default); + + if (error == SocketError.Success) { //Store socket on success _socket = _allArgs.AcceptSocket!; @@ -97,9 +100,8 @@ namespace VNLib.Net.Transport.Tcp */ _recvTask = SocketWorker.RecvDoWorkAsync(this, _allArgs.BytesTransferred, recvBuffSize); } - - //Clear the buffer reference - _allArgs.SetBuffer(default); + + _allArgs.AcceptSocket = null; return error; } @@ -126,6 +128,18 @@ namespace VNLib.Net.Transport.Tcp //Wait for recv to complete await _recvTask.ConfigureAwait(false); + /* + * Sockets are reused as much as possible on Windows. If the socket + * failes to disconnect cleanly, the release function won't clean it up + * so it needs to be cleaned up here so at least our args instance + * can be reused. + */ + if(IsWindows && error != SocketError.Success) + { + _socket.Dispose(); + _socket = null; + } + return error; } @@ -154,6 +168,8 @@ namespace VNLib.Net.Transport.Tcp void IReusable.Prepare() { + Debug.Assert(_socket == null || IsWindows, "Exepcted stale socket to be NULL on non-Windows platform"); + _allArgs.Prepare(); _recvArgs.Prepare(); SocketWorker.Prepare(); @@ -168,7 +184,7 @@ namespace VNLib.Net.Transport.Tcp _allArgs.Release(); _recvArgs.Release(); - //if the sockeet is connected (or not windows), dispose it and clear the accept socket + //if the socket is still 'connected' (or not windows), dispose it and clear the accept socket if (_socket?.Connected == true || !IsWindows) { _socket?.Dispose(); @@ -304,7 +320,6 @@ namespace VNLib.Net.Transport.Tcp { //Async disconnect return new ValueTask<SocketError>(this, AsyncTaskCore.Version); - } return ValueTask.FromResult(SocketError); diff --git a/lib/Net.Transport.SimpleTCP/src/SocketPipeLineWorker.cs b/lib/Net.Transport.SimpleTCP/src/SocketPipeLineWorker.cs index 428ad1f..b6df58c 100644 --- a/lib/Net.Transport.SimpleTCP/src/SocketPipeLineWorker.cs +++ b/lib/Net.Transport.SimpleTCP/src/SocketPipeLineWorker.cs @@ -52,6 +52,8 @@ namespace VNLib.Net.Transport.Tcp private readonly Timer SendTimer; private readonly Stream RecvStream; + private bool _started; + /// <summary> /// Initalizes a new reusable socket pipeline worker /// </summary> @@ -82,10 +84,16 @@ namespace VNLib.Net.Transport.Tcp { _sysSocketBufferSize = 0; - //Reset pipes for use - SendPipe.Reset(); - RecvPipe.Reset(); + //Only reset pipeline if it was started + if (_started) + { + //Reset pipes for use + SendPipe.Reset(); + RecvPipe.Reset(); + } + //clear started flag + _started = false; return true; } @@ -136,6 +144,8 @@ namespace VNLib.Net.Transport.Tcp ReadOnlySequence<byte>.Enumerator enumerator; ForwardOnlyMemoryReader<byte> segmentReader; + _started |= true; + try { _sysSocketBufferSize = sendBufferSize; @@ -231,6 +241,8 @@ namespace VNLib.Net.Transport.Tcp Exception? cause = null; Memory<byte> buffer; + _started |= true; + try { //If initial data was buffered, it needs to be published to the reader diff --git a/lib/Net.Transport.SimpleTCP/src/TcpServer.cs b/lib/Net.Transport.SimpleTCP/src/TcpServer.cs index 67a1751..08625d2 100644 --- a/lib/Net.Transport.SimpleTCP/src/TcpServer.cs +++ b/lib/Net.Transport.SimpleTCP/src/TcpServer.cs @@ -278,8 +278,6 @@ namespace VNLib.Net.Transport.Tcp /// <exception cref="InvalidOperationException"></exception> public ValueTask<ITcpConnectionDescriptor> AcceptConnectionAsync(CancellationToken cancellation) { - _ = WaitingSockets ?? throw new InvalidOperationException("Server is not listening"); - //Try get args from queue if (WaitingSockets.TryDequeue(out ITcpConnectionDescriptor? args)) { @@ -293,16 +291,18 @@ namespace VNLib.Net.Transport.Tcp /// Cleanly closes an existing TCP connection obtained from <see cref="AcceptConnectionAsync(CancellationToken)"/> /// and returns the instance to the pool for reuse. /// <para> - /// You should destroy all references to the - /// connection descriptor and dispose the stream returned from <see cref="ITcpConnectionDescriptor.GetStream"/> + /// If you set <paramref name="reuse"/> to true, the server will attempt to reuse the descriptor instance, you + /// must ensure that all previous references to the descriptor are destroyed. If the value is false, resources + /// are freed and the instance is disposed. /// </para> /// </summary> /// <param name="descriptor">The existing descriptor to close</param> + /// <param name="reuse">A value that indicates if the server can safley reuse the descriptor instance</param> /// <returns>A task that represents the closing operations</returns> /// <exception cref="ArgumentNullException"></exception> - public async ValueTask CloseConnectionAsync(ITcpConnectionDescriptor descriptor) + public async ValueTask CloseConnectionAsync(ITcpConnectionDescriptor descriptor, bool reuse) { - ArgumentNullException.ThrowIfNull(descriptor, nameof(descriptor)); + ArgumentNullException.ThrowIfNull(descriptor); //Recover args AwaitableAsyncServerSocket args = (AwaitableAsyncServerSocket)descriptor; @@ -312,15 +312,21 @@ namespace VNLib.Net.Transport.Tcp //Close the socket and cleanup resources SocketError err = await args.CloseConnectionAsync(); - if (err == SocketError.Success) + if (err != SocketError.Success) + { + _config.Log.Verbose("Socket disconnect failed with error code {ec}.", err); + } + + //See if we can reuse the args + if (reuse) { //Return to pool SockAsyncArgPool.Return(args); } else { + //Dispose args.Dispose(); - _config.Log.Verbose("Socket disconnected failed with error code {ec}. Resources disposed", err); } } |