Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ public partial class SendPacketsElement
public SendPacketsElement(byte[] buffer) { }
public SendPacketsElement(byte[] buffer, int offset, int count) { }
public SendPacketsElement(byte[] buffer, int offset, int count, bool endOfPacket) { }
public SendPacketsElement(ReadOnlyMemory<byte> buffer) { }
public SendPacketsElement(ReadOnlyMemory<byte> buffer, bool endOfPacket) { }
public SendPacketsElement(System.IO.FileStream fileStream) { }
public SendPacketsElement(System.IO.FileStream fileStream, long offset, int count) { }
public SendPacketsElement(System.IO.FileStream fileStream, long offset, int count, bool endOfPacket) { }
Expand All @@ -247,6 +249,7 @@ public SendPacketsElement(string filepath, long offset, int count, bool endOfPac
public bool EndOfPacket { get { throw null; } }
public string? FilePath { get { throw null; } }
public System.IO.FileStream? FileStream { get { throw null; } }
public ReadOnlyMemory<byte>? MemoryBuffer { get { throw null; } }
public int Offset { get { throw null; } }
public long OffsetLong { get { throw null; } }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public SendPacketsElement(string filepath, long offset, int count, bool endOfPac
throw new ArgumentOutOfRangeException(nameof(count));
}

Initialize(filepath, null, null, offset, count, endOfPacket);
Initialize(filepath, null, null, null, offset, count, endOfPacket);
}

// Constructors for fileStream elements.
Expand Down Expand Up @@ -75,7 +75,7 @@ public SendPacketsElement(FileStream fileStream, long offset, int count, bool en
throw new ArgumentOutOfRangeException(nameof(count));
}

Initialize(null, fileStream, null, offset, count, endOfPacket);
Initialize(null, fileStream, null, null, offset, count, endOfPacket);
}

// Constructors for buffer elements.
Expand All @@ -102,14 +102,24 @@ public SendPacketsElement(byte[] buffer, int offset, int count, bool endOfPacket
throw new ArgumentOutOfRangeException(nameof(count));
}

Initialize(null, null, buffer, offset, count, endOfPacket);
Initialize(null, null, buffer, new ReadOnlyMemory<byte>(buffer, offset, count), offset, count, endOfPacket);
}

private void Initialize(string? filePath, FileStream? fileStream, byte[]? buffer, long offset, int count, bool endOfPacket)
public SendPacketsElement(ReadOnlyMemory<byte> buffer) :
this(buffer, endOfPacket: false)
{ }

public SendPacketsElement(ReadOnlyMemory<byte> buffer, bool endOfPacket)
{
Initialize(null, null, null, buffer, 0, buffer.Length, endOfPacket);
}

private void Initialize(string? filePath, FileStream? fileStream, byte[]? buffer, ReadOnlyMemory<byte>? memoryBuffer, long offset, int count, bool endOfPacket)
{
FilePath = filePath;
FileStream = fileStream;
Buffer = buffer;
MemoryBuffer = memoryBuffer;
Comment thread
geoffkizer marked this conversation as resolved.
OffsetLong = offset;
Count = count;
EndOfPacket = endOfPacket;
Expand All @@ -123,6 +133,8 @@ private void Initialize(string? filePath, FileStream? fileStream, byte[]? buffer

public int Count { get; private set; }

public ReadOnlyMemory<byte>? MemoryBuffer { get; private set; }

public int Offset => checked((int)OffsetLong);

public long OffsetLong { get; private set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private enum SingleBufferHandleState : byte
// Note that these arrays are allocated and then grown as necessary, but never shrunk.
// Thus the actual in-use length is defined by _bufferListInternal.Count, not the length of these arrays.
private WSABuffer[]? _wsaBufferArrayPinned;
private GCHandle[]? _multipleBufferGCHandles;
private MemoryHandle[]? _multipleBufferMemoryHandles;

// Internal buffers for WSARecvMsg
private byte[]? _wsaMessageBufferPinned;
Expand Down Expand Up @@ -703,7 +703,7 @@ internal unsafe SocketError DoOperationSendPackets(Socket socket, SafeSocketHand
{
sendPacketsElementsFileStreamCount++;
}
else if (spe.Buffer != null && spe.Count > 0)
else if (spe.MemoryBuffer != null && spe.Count > 0)
{
sendPacketsElementsBufferCount++;
}
Expand Down Expand Up @@ -865,28 +865,17 @@ private void SetupMultipleBuffers()
{
int bufferCount = _bufferListInternal.Count;

#if DEBUG
if (_multipleBufferGCHandles != null)
{
foreach (GCHandle gcHandle in _multipleBufferGCHandles)
{
Debug.Assert(!gcHandle.IsAllocated);
}
}
#endif

// Number of things to pin is number of buffers.
// Ensure we have properly sized object array.
if (_multipleBufferGCHandles == null || (_multipleBufferGCHandles.Length < bufferCount))
if (_multipleBufferMemoryHandles == null || (_multipleBufferMemoryHandles.Length < bufferCount))
{
_multipleBufferGCHandles = new GCHandle[bufferCount];
_multipleBufferMemoryHandles = new MemoryHandle[bufferCount];
}

// Pin the buffers.
for (int i = 0; i < bufferCount; i++)
{
Debug.Assert(!_multipleBufferGCHandles[i].IsAllocated);
_multipleBufferGCHandles[i] = GCHandle.Alloc(_bufferListInternal[i].Array, GCHandleType.Pinned);
_multipleBufferMemoryHandles[i] = _bufferListInternal[i].Array.AsMemory().Pin();
}

if (_wsaBufferArrayPinned == null || _wsaBufferArrayPinned.Length < bufferCount)
Expand Down Expand Up @@ -973,14 +962,12 @@ private void FreePinHandles()
_singleBufferHandle.Dispose();
}

if (_multipleBufferGCHandles != null)
if (_multipleBufferMemoryHandles != null)
{
for (int i = 0; i < _multipleBufferGCHandles.Length; i++)
for (int i = 0; i < _multipleBufferMemoryHandles.Length; i++)
{
if (_multipleBufferGCHandles[i].IsAllocated)
{
_multipleBufferGCHandles[i].Free();
}
_multipleBufferMemoryHandles[i].Dispose();
_multipleBufferMemoryHandles[i] = default;
}
}

Expand All @@ -1007,50 +994,40 @@ private unsafe Interop.Winsock.TransmitPacketsElement[] SetupPinHandlesSendPacke

// Number of things to pin is number of buffers + 1 (native descriptor).
// Ensure we have properly sized object array.
#if DEBUG
if (_multipleBufferGCHandles != null)
if (_multipleBufferMemoryHandles == null || (_multipleBufferMemoryHandles.Length < sendPacketsElementsBufferCount))
{
foreach (GCHandle gcHandle in _multipleBufferGCHandles)
{
Debug.Assert(!gcHandle.IsAllocated);
}
}
#endif

if (_multipleBufferGCHandles == null || (_multipleBufferGCHandles.Length < sendPacketsElementsBufferCount))
{
_multipleBufferGCHandles = new GCHandle[sendPacketsElementsBufferCount];
_multipleBufferMemoryHandles = new MemoryHandle[sendPacketsElementsBufferCount];
}

// Pin user specified buffers.
int index = 0;
foreach (SendPacketsElement spe in sendPacketsElementsCopy)
{
if (spe?.Buffer != null && spe.Count > 0)
if (spe?.MemoryBuffer != null && spe.Count > 0)
{
Debug.Assert(!_multipleBufferGCHandles[index].IsAllocated);
_multipleBufferGCHandles[index] = GCHandle.Alloc(spe.Buffer, GCHandleType.Pinned);

_multipleBufferMemoryHandles[index] = spe.MemoryBuffer.Value.Pin();
index++;
}
}

// Fill in native descriptor.
int bufferIndex = 0;
int descriptorIndex = 0;
int fileIndex = 0;
foreach (SendPacketsElement spe in sendPacketsElementsCopy)
{
if (spe != null)
{
if (spe.Buffer != null && spe.Count > 0)
if (spe.MemoryBuffer != null && spe.Count > 0)
{
// This element is a buffer.
sendPacketsDescriptorPinned[descriptorIndex].buffer = Marshal.UnsafeAddrOfPinnedArrayElement(spe.Buffer, spe.Offset);
sendPacketsDescriptorPinned[descriptorIndex].buffer = (IntPtr)_multipleBufferMemoryHandles[bufferIndex].Pointer;
sendPacketsDescriptorPinned[descriptorIndex].length = (uint)spe.Count;
sendPacketsDescriptorPinned[descriptorIndex].flags =
Interop.Winsock.TransmitPacketsElementFlags.Memory | (spe.EndOfPacket
? Interop.Winsock.TransmitPacketsElementFlags.EndOfPacket
: 0);
bufferIndex++;
descriptorIndex++;
}
else if (spe.FilePath != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1797,9 +1797,9 @@ public static async void SendPacketsAsync(
SendPacketsElement e = elements[i];
if (e != null)
{
if (e.Buffer != null)
if (e.MemoryBuffer != null)
{
bytesTransferred += await socket.SendAsync(new ArraySegment<byte>(e.Buffer, e.Offset, e.Count), SocketFlags.None).ConfigureAwait(false);
bytesTransferred += await socket.SendAsync(e.MemoryBuffer.Value, SocketFlags.None).ConfigureAwait(false);
}
else
{
Expand Down
Loading