diff --git a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj
index 42314da6c7e9d..c576e1be3c000 100644
--- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj
+++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj
@@ -43,7 +43,6 @@
-
@@ -89,7 +88,6 @@
-
@@ -184,7 +182,6 @@
Link="Common\System\Net\CompletionPortHelper.Windows.cs" />
-
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.Unix.cs
deleted file mode 100644
index 657544b27c319..0000000000000
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.Unix.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Diagnostics;
-using System.Net;
-using System.Runtime.InteropServices;
-using System.Threading;
-using Microsoft.Win32;
-
-namespace System.Net.Sockets
-{
- // AcceptOverlappedAsyncResult - used to take care of storage for async Socket BeginAccept call.
- internal sealed partial class AcceptOverlappedAsyncResult : BaseOverlappedAsyncResult
- {
- private Socket? _acceptedSocket;
-
- internal Socket? AcceptSocket
- {
- set
- {
- // *nix does not support the reuse of an existing socket as the accepted
- // socket.
- Debug.Assert(value == null, $"Unexpected value: {value}");
- }
- }
-
- public void CompletionCallback(IntPtr acceptedFileDescriptor, byte[] socketAddress, int socketAddressLen, SocketError errorCode)
- {
- _buffer = null;
- _numBytes = 0;
-
- if (errorCode == SocketError.Success)
- {
- Debug.Assert(_listenSocket._rightEndPoint != null);
-
- Internals.SocketAddress remoteSocketAddress = IPEndPointExtensions.Serialize(_listenSocket._rightEndPoint);
- System.Buffer.BlockCopy(socketAddress, 0, remoteSocketAddress.Buffer, 0, socketAddressLen);
-
- _acceptedSocket = _listenSocket.CreateAcceptSocket(
- SocketPal.CreateSocket(acceptedFileDescriptor),
- _listenSocket._rightEndPoint.Create(remoteSocketAddress));
- }
-
- base.CompletionCallback(0, errorCode);
- }
-
- internal override object? PostCompletion(int numBytes)
- {
- _numBytes = numBytes;
- return (SocketError)ErrorCode == SocketError.Success ? _acceptedSocket : null;
- }
- }
-}
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.Windows.cs
deleted file mode 100644
index d85b2bfc8c4af..0000000000000
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.Windows.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace System.Net.Sockets
-{
- // AcceptOverlappedAsyncResult - used to take care of storage for async Socket BeginAccept call.
- internal sealed partial class AcceptOverlappedAsyncResult : BaseOverlappedAsyncResult
- {
- private Socket? _acceptSocket;
- private int _addressBufferLength;
-
- // This method will be called by us when the IO completes synchronously and
- // by the ThreadPool when the IO completes asynchronously. (only called on WinNT)
- internal override object? PostCompletion(int numBytes)
- {
- SocketError errorCode = (SocketError)ErrorCode;
-
- Internals.SocketAddress? remoteSocketAddress = null;
- if (errorCode == SocketError.Success)
- {
- _numBytes = numBytes;
- if (NetEventSource.Log.IsEnabled()) LogBuffer(numBytes);
-
- // get the endpoint
- remoteSocketAddress = IPEndPointExtensions.Serialize(_listenSocket._rightEndPoint!);
-
- IntPtr localAddr;
- int localAddrLength;
- IntPtr remoteAddr;
-
- // set the socket context
- bool refAdded = false;
- SafeHandle safeHandle = _listenSocket.SafeHandle;
- try
- {
- safeHandle.DangerousAddRef(ref refAdded);
- IntPtr handle = safeHandle.DangerousGetHandle();
-
- Debug.Assert(_buffer != null);
- _listenSocket.GetAcceptExSockaddrs(
- Marshal.UnsafeAddrOfPinnedArrayElement(_buffer, 0),
- _buffer.Length - (_addressBufferLength * 2),
- _addressBufferLength,
- _addressBufferLength,
- out localAddr,
- out localAddrLength,
- out remoteAddr,
- out remoteSocketAddress.InternalSize);
-
- Marshal.Copy(remoteAddr, remoteSocketAddress.Buffer, 0, remoteSocketAddress.Size);
-
- errorCode = Interop.Winsock.setsockopt(
- _acceptSocket!.SafeHandle,
- SocketOptionLevel.Socket,
- SocketOptionName.UpdateAcceptContext,
- ref handle,
- IntPtr.Size);
-
- if (errorCode == SocketError.SocketError)
- {
- errorCode = SocketPal.GetLastSocketError();
- }
-
- if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"setsockopt handle:{handle}, AcceptSocket:{_acceptSocket}, returns:{errorCode}");
- }
- catch (ObjectDisposedException)
- {
- errorCode = SocketError.OperationAborted;
- }
- finally
- {
- if (refAdded)
- {
- safeHandle.DangerousRelease();
- }
- }
-
- ErrorCode = (int)errorCode;
- }
-
- if (errorCode != SocketError.Success)
- {
- return null;
- }
-
- return _listenSocket.UpdateAcceptSocket(_acceptSocket!, _listenSocket._rightEndPoint!.Create(remoteSocketAddress!));
- }
-
- // SetUnmanagedStructures
- //
- // This method fills in overlapped structures used in an asynchronous
- // overlapped Winsock call. These calls are outside the runtime and are
- // unmanaged code, so we need to prepare specific structures and ints that
- // lie in unmanaged memory since the overlapped calls may complete asynchronously.
- internal void SetUnmanagedStructures(byte[] buffer, int addressBufferLength)
- {
- // has to be called first to pin memory
- base.SetUnmanagedStructures(buffer);
-
- // Fill in Buffer Array structure that will be used for our send/recv Buffer
- _addressBufferLength = addressBufferLength;
- _buffer = buffer;
- }
-
- private void LogBuffer(long size)
- {
- // This should only be called if tracing is enabled. However, there is the potential for a race
- // condition where tracing is disabled between a calling check and here, in which case the assert
- // may fire erroneously.
- Debug.Assert(NetEventSource.Log.IsEnabled());
- Debug.Assert(_buffer != null);
-
- if (size > -1)
- {
- NetEventSource.DumpBuffer(this, _buffer, 0, Math.Min((int)size, _buffer.Length));
- }
- else
- {
- NetEventSource.DumpBuffer(this, _buffer);
- }
- }
-
- internal Socket AcceptSocket
- {
- set
- {
- _acceptSocket = value;
- }
- }
- }
-}
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.cs
deleted file mode 100644
index 5e6609fedffa0..0000000000000
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/AcceptOverlappedAsyncResult.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Net.Sockets
-{
- // AcceptOverlappedAsyncResult - used to take care of storage for async Socket BeginAccept call.
- internal sealed partial class AcceptOverlappedAsyncResult : BaseOverlappedAsyncResult
- {
- private readonly Socket _listenSocket;
- private byte[]? _buffer;
-
- internal AcceptOverlappedAsyncResult(Socket listenSocket, object? asyncState, AsyncCallback? asyncCallback) :
- base(listenSocket, asyncState, asyncCallback)
- {
- _listenSocket = listenSocket;
- }
-
- internal byte[]? Buffer
- {
- get
- {
- return _buffer;
- }
- }
-
- internal int BytesTransferred
- {
- get
- {
- return _numBytes;
- }
- }
- }
-}
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs
index 79ba1e95c1d3f..a46a30555fd43 100644
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs
+++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Unix.cs
@@ -27,26 +27,6 @@ public SocketInformation DuplicateAndClose(int targetProcessId)
throw new PlatformNotSupportedException(SR.net_sockets_duplicateandclose_notsupported);
}
- public IAsyncResult BeginAccept(int receiveSize, AsyncCallback? callback, object? state)
- {
- throw new PlatformNotSupportedException(SR.net_sockets_accept_receive_apm_notsupported);
- }
-
- public IAsyncResult BeginAccept(Socket? acceptSocket, int receiveSize, AsyncCallback? callback, object? state)
- {
- throw new PlatformNotSupportedException(SR.net_sockets_accept_receive_apm_notsupported);
- }
-
- public Socket EndAccept(out byte[] buffer, IAsyncResult asyncResult)
- {
- throw new PlatformNotSupportedException(SR.net_sockets_accept_receive_apm_notsupported);
- }
-
- public Socket EndAccept(out byte[] buffer, out int bytesTransferred, IAsyncResult asyncResult)
- {
- throw new PlatformNotSupportedException(SR.net_sockets_accept_receive_apm_notsupported);
- }
-
internal bool PreferInlineCompletions
{
get => _handle.PreferInlineCompletions;
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs
index 11325495e0a31..417386efaddcd 100644
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs
+++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs
@@ -7,6 +7,7 @@
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
+using System.Threading.Tasks;
using System.Runtime.Versioning;
namespace System.Net.Sockets
@@ -145,30 +146,6 @@ public SocketInformation DuplicateAndClose(int targetProcessId)
return info;
}
- public IAsyncResult BeginAccept(int receiveSize, AsyncCallback? callback, object? state)
- {
- return BeginAccept(acceptSocket: null, receiveSize, callback, state);
- }
-
- // This is the truly async version that uses AcceptEx.
- public IAsyncResult BeginAccept(Socket? acceptSocket, int receiveSize, AsyncCallback? callback, object? state)
- {
- return BeginAcceptCommon(acceptSocket, receiveSize, callback, state);
- }
-
- public Socket EndAccept(out byte[] buffer, IAsyncResult asyncResult)
- {
- Socket socket = EndAccept(out byte[] innerBuffer, out int bytesTransferred, asyncResult);
- buffer = new byte[bytesTransferred];
- Buffer.BlockCopy(innerBuffer, 0, buffer, 0, bytesTransferred);
- return socket;
- }
-
- public Socket EndAccept(out byte[] buffer, out int bytesTransferred, IAsyncResult asyncResult)
- {
- return EndAcceptCommon(out buffer!, out bytesTransferred, asyncResult);
- }
-
private DynamicWinsockMethods GetDynamicWinsockMethods()
{
return _dynamicWinsockMethods ??= DynamicWinsockMethods.GetMethods(_addressFamily, _socketType, _protocolType);
@@ -439,7 +416,7 @@ private IAsyncResult BeginSendFileInternal(string? fileName, byte[]? preBuffer,
throw new SocketException((int)errorCode);
}
- asyncResult.FinishPostingAsyncOp(ref Caches.SendClosureCache);
+ asyncResult.FinishPostingAsyncOp();
return asyncResult;
}
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
index d39abf6609ba5..796bd6e3fa8f7 100644
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
+++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
@@ -57,16 +57,6 @@ public partial class Socket : IDisposable
private SocketType _socketType;
private ProtocolType _protocolType;
- // These caches are one degree off of Socket since they're not used in the sync case/when disabled in config.
- private CacheSet? _caches;
-
- private sealed class CacheSet
- {
- internal CallbackClosure? AcceptClosureCache;
- internal CallbackClosure? SendClosureCache;
- internal CallbackClosure? ReceiveClosureCache;
- }
-
// Bool marked true if the native socket option IP_PKTINFO or IPV6_PKTINFO has been set.
private bool _receivingPacketInformation;
@@ -2124,7 +2114,7 @@ public void EndConnect(IAsyncResult asyncResult)
}
public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback? callback, object? state) =>
- TaskToApmBeginWithSyncExceptions(DisconnectAsync(reuseSocket).AsTask(), callback, state);
+ TaskToApm.Begin(DisconnectAsync(reuseSocket).AsTask(), callback, state);
public void Disconnect(bool reuseSocket)
{
@@ -2421,166 +2411,72 @@ public int EndReceiveFrom(IAsyncResult asyncResult, ref EndPoint endPoint)
return result.ReceivedBytes;
}
- // Routine Description:
- //
- // BeginAccept - Does an async winsock accept, creating a new socket on success
- //
- // Works by creating a pending accept request the first time,
- // and subsequent calls are queued so that when the first accept completes,
- // the next accept can be resubmitted in the callback.
- // this routine may go pending at which time,
- // but any case the callback Delegate will be called upon completion
- //
- // Arguments:
- //
- // Callback - Async Callback Delegate that is called upon Async Completion
- // State - State used to track callback, set by caller, not required
- //
- // Return Value:
- //
- // IAsyncResult - Async result used to retrieve resultant new socket
- public IAsyncResult BeginAccept(AsyncCallback? callback, object? state)
- {
- if (!_isDisconnected)
- {
- return BeginAcceptCommon(acceptSocket: null, receiveSize: 0, callback, state);
- }
-
- Debug.Assert(Disposed);
- ThrowObjectDisposedException();
- return null; // unreachable
- }
+ public IAsyncResult BeginAccept(AsyncCallback? callback, object? state) =>
+ TaskToApm.Begin(AcceptAsync(), callback, state);
- private IAsyncResult BeginAcceptCommon(Socket? acceptSocket, int receiveSize, AsyncCallback? callback, object? state)
+ public Socket EndAccept(IAsyncResult asyncResult)
{
ThrowIfDisposed();
+ return TaskToApm.End(asyncResult);
+ }
+ // This method provides support for legacy BeginAccept methods that take a "receiveSize" argument and
+ // allow data to be received as part of the accept operation.
+ // There's no direct equivalent of this in the Task APIs, so we mimic it here.
+ private async Task<(Socket s, byte[] buffer, int bytesReceived)> AcceptAndReceiveHelperAsync(Socket? acceptSocket, int receiveSize)
+ {
// Validate input parameters.
if (receiveSize < 0)
{
throw new ArgumentOutOfRangeException(nameof(receiveSize));
}
- // Set up the async result with flowing.
- AcceptOverlappedAsyncResult asyncResult = new AcceptOverlappedAsyncResult(this, state, callback);
- asyncResult.StartPostingAsyncOp(false);
-
- // Start the accept.
- if (_rightEndPoint == null)
- {
- throw new InvalidOperationException(SR.net_sockets_mustbind);
- }
+ Socket s = await AcceptAsync(acceptSocket).ConfigureAwait(false);
- if (!_isListening)
+ byte[] buffer;
+ int bytesReceived;
+ if (receiveSize == 0)
{
- throw new InvalidOperationException(SR.net_sockets_mustlisten);
+ buffer = Array.Empty();
+ bytesReceived = 0;
}
-
- SafeSocketHandle? acceptHandle;
- asyncResult.AcceptSocket = GetOrCreateAcceptSocket(acceptSocket, false, nameof(acceptSocket), out acceptHandle);
-
- if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"AcceptSocket:{acceptSocket}");
- if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AcceptStart(_rightEndPoint);
-
- int socketAddressSize = GetAddressSize(_rightEndPoint);
- SocketError errorCode;
- try
- {
- errorCode = SocketPal.AcceptAsync(this, _handle, acceptHandle, receiveSize, socketAddressSize, asyncResult);
- }
- catch (Exception ex)
+ else
{
- if (SocketsTelemetry.Log.IsEnabled())
+ buffer = new byte[receiveSize];
+ try
{
- SocketsTelemetry.Log.AfterAccept(SocketError.Interrupted, ex.Message);
+ bytesReceived = await s.ReceiveAsync(buffer, SocketFlags.None).ConfigureAwait(false);
+ }
+ catch
+ {
+ s.Dispose();
+ throw;
}
-
- throw;
}
- if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"AcceptAsync returns:{errorCode} {asyncResult}");
-
- // Throw an appropriate SocketException if the native call fails synchronously.
- if (!CheckErrorAndUpdateStatus(errorCode))
- {
- UpdateAcceptSocketErrorForDisposed(ref errorCode);
-
- if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AfterAccept(errorCode);
-
- throw new SocketException((int)errorCode);
- }
+ return (s, buffer, bytesReceived);
+ }
- // Finish the flow capture, maybe complete here.
- asyncResult.FinishPostingAsyncOp(ref Caches.AcceptClosureCache);
+ public IAsyncResult BeginAccept(int receiveSize, AsyncCallback? callback, object? state) =>
+ BeginAccept(acceptSocket: null, receiveSize, callback, state);
- return asyncResult;
- }
+ public IAsyncResult BeginAccept(Socket? acceptSocket, int receiveSize, AsyncCallback? callback, object? state) =>
+ TaskToApm.Begin(AcceptAndReceiveHelperAsync(acceptSocket, receiveSize), callback, state);
- // Routine Description:
- //
- // EndAccept - Called by user code after I/O is done or the user wants to wait.
- // until Async completion, so it provides End handling for async Accept calls,
- // and retrieves new Socket object
- //
- // Arguments:
- //
- // AsyncResult - the AsyncResult Returned from BeginAccept call
- //
- // Return Value:
- //
- // Socket - a valid socket if successful
- public Socket EndAccept(IAsyncResult asyncResult)
+ public Socket EndAccept(out byte[] buffer, IAsyncResult asyncResult)
{
- return EndAcceptCommon(out _, out _, asyncResult);
+ Socket socket = EndAccept(out byte[] innerBuffer, out int bytesTransferred, asyncResult);
+ buffer = new byte[bytesTransferred];
+ Buffer.BlockCopy(innerBuffer, 0, buffer, 0, bytesTransferred);
+ return socket;
}
- private Socket EndAcceptCommon(out byte[]? buffer, out int bytesTransferred, IAsyncResult asyncResult)
- {
- if (Disposed)
- {
- if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AfterAccept(SocketError.Interrupted);
-
- ThrowObjectDisposedException();
- }
-
- // Validate input parameters.
- if (asyncResult == null)
- {
- throw new ArgumentNullException(nameof(asyncResult));
- }
- AcceptOverlappedAsyncResult? castedAsyncResult = asyncResult as AcceptOverlappedAsyncResult;
- if (castedAsyncResult == null || castedAsyncResult.AsyncObject != this)
- {
- throw new ArgumentException(SR.net_io_invalidasyncresult, nameof(asyncResult));
- }
- if (castedAsyncResult.EndCalled)
- {
- throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndAccept"));
- }
-
- Socket socket = (Socket)castedAsyncResult.InternalWaitForCompletion()!;
- bytesTransferred = (int)castedAsyncResult.BytesTransferred;
- buffer = castedAsyncResult.Buffer;
-
- if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.BytesReceived(bytesTransferred);
- castedAsyncResult.EndCalled = true;
-
- // Throw an appropriate SocketException if the native call failed asynchronously.
- SocketError errorCode = (SocketError)castedAsyncResult.ErrorCode;
-
- if (errorCode != SocketError.Success)
- {
- UpdateAcceptSocketErrorForDisposed(ref errorCode);
-
- if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AfterAccept(errorCode);
-
- UpdateStatusAfterSocketErrorAndThrowException(errorCode);
- }
-
- if (SocketsTelemetry.Log.IsEnabled()) SocketsTelemetry.Log.AfterAccept(SocketError.Success);
-
- if (NetEventSource.Log.IsEnabled()) NetEventSource.Accepted(socket, socket.RemoteEndPoint, socket.LocalEndPoint);
- return socket;
+ public Socket EndAccept(out byte[] buffer, out int bytesTransferred, IAsyncResult asyncResult)
+ {
+ ThrowIfDisposed();
+ Socket s;
+ (s, buffer, bytesTransferred) = TaskToApm.End<(Socket, byte[], int)>(asyncResult);
+ return s;
}
// Disables sends and receives on a socket.
@@ -3102,19 +2998,6 @@ private bool SendToAsync(SocketAsyncEventArgs e, CancellationToken cancellationT
// Internal and private properties
//
- private CacheSet Caches
- {
- get
- {
- if (_caches == null)
- {
- // It's not too bad if extra of these are created and lost.
- _caches = new CacheSet();
- }
- return _caches;
- }
- }
-
internal bool Disposed => _disposed != 0;
//
@@ -3831,17 +3714,5 @@ private static SocketError GetSocketErrorFromFaultedTask(Task t)
_ => SocketError.SocketError
};
}
-
- // Helper to maintain existing behavior of Socket APM methods to throw synchronously from Begin*.
- private static IAsyncResult TaskToApmBeginWithSyncExceptions(Task task, AsyncCallback? callback, object? state)
- {
- if (task.IsFaulted)
- {
- task.GetAwaiter().GetResult();
- Debug.Fail("Task faulted but GetResult did not throw???");
- }
-
- return TaskToApm.Begin(task, callback, state);
- }
}
}
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
index 5b926330aac35..5ccc4d640b3d0 100644
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
+++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs
@@ -1959,23 +1959,6 @@ public static async void SendPacketsAsync(
}
}
- public static SocketError AcceptAsync(Socket socket, SafeSocketHandle handle, SafeSocketHandle? acceptHandle, int receiveSize, int socketAddressSize, AcceptOverlappedAsyncResult asyncResult)
- {
- Debug.Assert(acceptHandle == null, $"Unexpected acceptHandle: {acceptHandle}");
- Debug.Assert(receiveSize == 0, $"Unexpected receiveSize: {receiveSize}");
-
- byte[] socketAddressBuffer = new byte[socketAddressSize];
-
- IntPtr acceptedFd;
- SocketError socketError = handle.AsyncContext.AcceptAsync(socketAddressBuffer, ref socketAddressSize, out acceptedFd, asyncResult.CompletionCallback);
- if (socketError == SocketError.Success)
- {
- asyncResult.CompletionCallback(acceptedFd, socketAddressBuffer, socketAddressSize, SocketError.Success);
- }
-
- return socketError;
- }
-
internal static SocketError Disconnect(Socket socket, SafeSocketHandle handle, bool reuseSocket)
{
handle.SetToDisconnected();
diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs
index e902d22c049bc..8d109203f72fe 100644
--- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs
+++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs
@@ -1,15 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.Win32.SafeHandles;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
+using Microsoft.Win32.SafeHandles;
#if BIGENDIAN
using System.Buffers.Binary;
@@ -1099,39 +1098,6 @@ public static unsafe SocketError SendFileAsync(SafeSocketHandle handle, FileStre
}
}
- public static unsafe SocketError AcceptAsync(Socket socket, SafeSocketHandle handle, SafeSocketHandle acceptHandle, int receiveSize, int socketAddressSize, AcceptOverlappedAsyncResult asyncResult)
- {
- // The buffer needs to contain the requested data plus room for two sockaddrs and 16 bytes
- // of associated data for each.
- int addressBufferSize = socketAddressSize + 16;
- byte[] buffer = new byte[receiveSize + ((addressBufferSize) * 2)];
-
- // Set up asyncResult for overlapped AcceptEx.
- // This call will use completion ports on WinNT.
- asyncResult.SetUnmanagedStructures(buffer, addressBufferSize);
- try
- {
- // This can throw ObjectDisposedException.
- int bytesTransferred;
- bool success = socket.AcceptEx(
- handle,
- acceptHandle,
- Marshal.UnsafeAddrOfPinnedArrayElement(asyncResult.Buffer!, 0),
- receiveSize,
- addressBufferSize,
- addressBufferSize,
- out bytesTransferred,
- asyncResult.DangerousOverlappedPointer); // SafeHandle was just created in SetUnmanagedStructures
-
- return asyncResult.ProcessOverlappedResult(success, 0);
- }
- catch
- {
- asyncResult.ReleaseUnmanagedStructures();
- throw;
- }
- }
-
public static void CheckDualModeReceiveSupport(Socket socket)
{
// Dual-mode sockets support received packet info on Windows.
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Accept.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Accept.cs
index 79756096973be..8a84756da35dd 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Accept.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Accept.cs
@@ -222,7 +222,7 @@ public async Task Accept_WithTargetSocket_ReuseAfterDisconnect_Success(bool reus
[OuterLoop]
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/1483", TestPlatforms.AnyUnix)]
- public void Accept_WithAlreadyBoundTargetSocket_Fails()
+ public async Task Accept_WithAlreadyBoundTargetSocket_Fails()
{
if (!SupportsAcceptIntoExistingSocket)
return;
@@ -236,7 +236,7 @@ public void Accept_WithAlreadyBoundTargetSocket_Fails()
server.BindToAnonymousPort(IPAddress.Loopback);
- Assert.Throws(() => { AcceptAsync(listener, server); });
+ await Assert.ThrowsAsync(() => AcceptAsync(listener, server));
}
}
@@ -262,7 +262,7 @@ public async Task Accept_WithInUseTargetSocket_Fails()
Assert.Same(server, accepted);
Assert.True(accepted.Connected);
- Assert.Throws(() => { AcceptAsync(listener, server); });
+ await Assert.ThrowsAsync(() => AcceptAsync(listener, server));
}
}
@@ -353,8 +353,7 @@ await RetryHelper.ExecuteAsync(async () =>
}
[Fact]
- [PlatformSpecific(TestPlatforms.Windows)]
- public async Task AcceptReceive_Windows_Success()
+ public async Task AcceptReceive_Success()
{
if (!SupportsAcceptReceive)
{
@@ -376,24 +375,6 @@ public async Task AcceptReceive_Windows_Success()
(_, byte[] recvBuffer) = await acceptTask;
Assert.Equal(new byte[] { 42 }, recvBuffer);
}
-
- [Fact]
- [PlatformSpecific(TestPlatforms.AnyUnix)]
- public void AcceptReceive_Unix_ThrowsPlatformNotSupportedException()
- {
- if (!SupportsAcceptReceive)
- {
- // Currently only supported by APM and EAP
- return;
- }
-
- using Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- int port = listener.BindToAnonymousPort(IPAddress.Loopback);
- IPEndPoint listenerEndpoint = new IPEndPoint(IPAddress.Loopback, port);
- listener.Listen(100);
-
- Assert.ThrowsAsync(() => AcceptAsync(listener, 1) );
- }
}
public sealed class AcceptSync : Accept
@@ -409,22 +390,6 @@ public AcceptSyncForceNonBlocking(ITestOutputHelper output) : base(output) {}
public sealed class AcceptApm : Accept
{
public AcceptApm(ITestOutputHelper output) : base(output) {}
-
- [Fact]
- [PlatformSpecific(TestPlatforms.AnyUnix)]
- public void EndAccept_AcceptReceiveUnix_ThrowsPlatformNotSupportedException()
- {
- using Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
-
- // Creating a fake IAsyncResult:
- int port = listener.BindToAnonymousPort(IPAddress.Loopback);
- IPEndPoint listenerEndpoint = new IPEndPoint(IPAddress.Loopback, port);
- listener.Listen(100);
- IAsyncResult iar = listener.BeginAccept(callback: null, state: null);
-
- Assert.Throws(() => listener.EndAccept(out _, iar));
- Assert.Throws(() => listener.EndAccept(out _, out _, iar));
- }
}
public sealed class AcceptTask : Accept
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisconnectTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisconnectTest.cs
index 1d343cb434f6d..1c0270eaca6bd 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisconnectTest.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisconnectTest.cs
@@ -120,27 +120,6 @@ public void EndDisconnect_InvalidArguments_Throws()
AssertExtensions.Throws("asyncResult", () => s.EndDisconnect(Task.CompletedTask));
}
}
-
- [Fact]
- public void BeginDisconnect_NotConnected_ThrowSync()
- {
- using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
- {
- Assert.Throws(() => s.BeginDisconnect(true, null, null));
- Assert.Throws(() => s.BeginDisconnect(false, null, null));
- }
- }
-
- [Fact]
- public void BeginDisconnection_ObjectDisposed_ThrowSync()
- {
- using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
- {
- s.Dispose();
- Assert.Throws(() => s.BeginDisconnect(true, null, null));
- Assert.Throws(() => s.BeginDisconnect(false, null, null));
- }
- }
}
public sealed class Disconnect_Task : Disconnect
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs
index b1de69b736601..983f7a23bb1a8 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs
@@ -139,7 +139,10 @@ public override Task AcceptAsync(Socket s) =>
return (socket, buffer);
}
public override Task AcceptAsync(Socket s, Socket acceptSocket) =>
- Task.Factory.FromAsync(s.BeginAccept, s.EndAccept, acceptSocket, 0, null);
+ Task.Factory.FromAsync(
+ (callback, state) => s.BeginAccept(acceptSocket, 0, callback, state),
+ result => s.EndAccept(out _, out _, result),
+ null);
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
Task.Factory.FromAsync(s.BeginConnect, s.EndConnect, endPoint, null);
public override Task MultiConnectAsync(Socket s, IPAddress[] addresses, int port) =>
@@ -291,7 +294,7 @@ public sealed class SocketHelperEap : SocketHelperBase
{
public override bool UsesEap => true;
public override bool ValidatesArrayArguments => false;
- public override bool SupportsAcceptReceive => true;
+ public override bool SupportsAcceptReceive => PlatformDetection.IsWindows;
public override Task AcceptAsync(Socket s) =>
InvokeAsync(s, e => e.AcceptSocket, e => s.AcceptAsync(e));