Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoid GCHandle in ConnectEx and SendTo on Windows #86524

Merged
merged 2 commits into from
May 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private static unsafe partial SocketError WSASendTo(
int bufferCount,
out int bytesTransferred,
SocketFlags socketFlags,
IntPtr socketAddress,
Span<byte> socketAddress,
MihaZupan marked this conversation as resolved.
Show resolved Hide resolved
int socketAddressSize,
NativeOverlapped* overlapped,
IntPtr completionRoutine);
Expand All @@ -29,16 +29,15 @@ internal static unsafe SocketError WSASendTo(
int bufferCount,
out int bytesTransferred,
SocketFlags socketFlags,
IntPtr socketAddress,
int socketAddressSize,
Span<byte> socketAddress,
MihaZupan marked this conversation as resolved.
Show resolved Hide resolved
NativeOverlapped* overlapped,
IntPtr completionRoutine)
{
// We intentionally do NOT copy this back after the function completes:
// We don't want to cause a race in async scenarios.
// The WSABuffer struct should be unchanged anyway.
WSABuffer localBuffer = buffer;
return WSASendTo(socketHandle, &localBuffer, bufferCount, out bytesTransferred, socketFlags, socketAddress, socketAddressSize, overlapped, completionRoutine);
return WSASendTo(socketHandle, &localBuffer, bufferCount, out bytesTransferred, socketFlags, socketAddress, socketAddress.Length, overlapped, completionRoutine);
}

internal static unsafe SocketError WSASendTo(
Expand All @@ -47,15 +46,14 @@ internal static unsafe SocketError WSASendTo(
int bufferCount,
[Out] out int bytesTransferred,
SocketFlags socketFlags,
IntPtr socketAddress,
int socketAddressSize,
Span<byte> socketAddress,
NativeOverlapped* overlapped,
IntPtr completionRoutine)
{
Debug.Assert(buffers != null && buffers.Length > 0);
fixed (WSABuffer* buffersPtr = &buffers[0])
{
return WSASendTo(socketHandle, buffersPtr, bufferCount, out bytesTransferred, socketFlags, socketAddress, socketAddressSize, overlapped, completionRoutine);
return WSASendTo(socketHandle, buffersPtr, bufferCount, out bytesTransferred, socketFlags, socketAddress, socketAddress.Length, overlapped, completionRoutine);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ internal unsafe void GetAcceptExSockaddrs(IntPtr buffer, int receiveDataLength,
Marshal.SetLastPInvokeError(Marshal.GetLastSystemError());

}
internal unsafe bool ConnectEx(SafeSocketHandle socketHandle, IntPtr socketAddress, int socketAddressSize, IntPtr buffer, int dataLength, out int bytesSent, NativeOverlapped* overlapped)
internal unsafe bool ConnectEx(SafeSocketHandle socketHandle, Span<byte> socketAddress, IntPtr buffer, int dataLength, out int bytesSent, NativeOverlapped* overlapped)
MihaZupan marked this conversation as resolved.
Show resolved Hide resolved
{
IntPtr __socketHandle_gen_native = default;
bytesSent = default;
Expand All @@ -192,8 +192,9 @@ internal unsafe bool ConnectEx(SafeSocketHandle socketHandle, IntPtr socketAddre
socketHandle.DangerousAddRef(ref socketHandle__addRefd);
__socketHandle_gen_native = socketHandle.DangerousGetHandle();
fixed (int* __bytesSent_gen_native = &bytesSent)
fixed (void* socketAddressPtr = socketAddress)
MihaZupan marked this conversation as resolved.
Show resolved Hide resolved
{
__retVal_gen_native = ((delegate* unmanaged<IntPtr, IntPtr, int, IntPtr, int, int*, NativeOverlapped*, int>)_target)(__socketHandle_gen_native, socketAddress, socketAddressSize, buffer, dataLength, __bytesSent_gen_native, overlapped);
__retVal_gen_native = ((delegate* unmanaged<IntPtr, void*, int, IntPtr, int, int*, NativeOverlapped*, int>)_target)(__socketHandle_gen_native, socketAddressPtr, socketAddress.Length, buffer, dataLength, __bytesSent_gen_native, overlapped);
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
}
Marshal.SetLastPInvokeError(Marshal.GetLastSystemError());
//
Expand Down Expand Up @@ -338,8 +339,7 @@ internal delegate void GetAcceptExSockaddrsDelegate(

internal unsafe delegate bool ConnectExDelegate(
SafeSocketHandle socketHandle,
IntPtr socketAddress,
int socketAddressSize,
Span<byte> socketAddress,
MihaZupan marked this conversation as resolved.
Show resolved Hide resolved
IntPtr buffer,
int dataLength,
out int bytesSent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,16 +266,15 @@ private void EnableReuseUnicastPort()
}

internal unsafe bool ConnectEx(SafeSocketHandle socketHandle,
IntPtr socketAddress,
int socketAddressSize,
Span<byte> socketAddress,
MihaZupan marked this conversation as resolved.
Show resolved Hide resolved
IntPtr buffer,
int dataLength,
out int bytesSent,
NativeOverlapped* overlapped)
{
ConnectExDelegate connectEx = GetDynamicWinsockMethods().GetConnectExDelegate(socketHandle);

return connectEx(socketHandle, socketAddress, socketAddressSize, buffer, dataLength, out bytesSent, overlapped);
return connectEx(socketHandle, socketAddress, buffer, dataLength, out bytesSent, overlapped);
}

internal unsafe SocketError WSARecvMsg(SafeSocketHandle socketHandle, IntPtr msg, out int bytesTransferred, NativeOverlapped* overlapped, IntPtr completionRoutine)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,6 @@ internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle

// ConnectEx uses a sockaddr buffer containing the remote address to which to connect.
// It can also optionally take a single buffer of data to send after the connection is complete.
// The sockaddr is pinned with a GCHandle to avoid having to use the object array form of UnsafePack.
PinSocketAddressBuffer();

fixed (byte* bufferPtr = &MemoryMarshal.GetReference(_buffer.Span))
{
Expand All @@ -305,8 +303,7 @@ internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle
{
bool success = socket.ConnectEx(
handle,
PtrSocketAddressBuffer,
_socketAddress!.Size,
_socketAddress!.Buffer.AsSpan(),
(IntPtr)(bufferPtr + _offset),
_count,
out int bytesTransferred,
Expand Down Expand Up @@ -743,9 +740,6 @@ internal unsafe SocketError DoOperationSendTo(SafeSocketHandle handle, Cancellat
// receive data and from which to send data respectively. Single and multiple buffers
// are handled differently so as to optimize performance for the more common single buffer case.
//
// WSARecvFrom and WSASendTo also uses a sockaddr buffer in which to store the address from which the data was received.
// The sockaddr is pinned with a GCHandle to avoid having to use the object array form of UnsafePack.
PinSocketAddressBuffer();

return _bufferList == null ?
DoOperationSendToSingleBuffer(handle, cancellationToken) :
Expand All @@ -769,8 +763,7 @@ internal unsafe SocketError DoOperationSendToSingleBuffer(SafeSocketHandle handl
1,
out int bytesTransferred,
_socketFlags,
PtrSocketAddressBuffer,
_socketAddress!.Size,
_socketAddress!.Buffer.AsSpan(),
overlapped,
IntPtr.Zero);

Expand All @@ -797,8 +790,7 @@ internal unsafe SocketError DoOperationSendToMultiBuffer(SafeSocketHandle handle
_bufferListInternal!.Count,
out int bytesTransferred,
_socketFlags,
PtrSocketAddressBuffer,
_socketAddress!.Size,
_socketAddress!.Buffer.AsSpan(),
overlapped,
IntPtr.Zero);

Expand Down