Skip to content

Commit

Permalink
Merge several version of MsQuicStream SendAsync code (#68772)
Browse files Browse the repository at this point in the history
* Merge several version of MsQuicStream SendAsync code

* Use shared MsQuicBuffers struct

* Minor changes

* Fixes after rebase

* Code review feedback

* Use static lambdas instead of adapter structs

* Minor change

* fixup! Minor change
  • Loading branch information
rzikm committed May 24, 2022
1 parent 326e719 commit fff4ff0
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 224 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,35 +39,91 @@ private void FreeNativeMemory()
NativeMemory.Free(buffers);
}

private void Reserve(int count)
{
if (_handles.Length < count)
{
_handles = new MemoryHandle[count];
FreeNativeMemory();
_buffers = (QUIC_BUFFER*)NativeMemory.Alloc((nuint)count, (nuint)sizeof(QUIC_BUFFER));
}

_count = count;
}

private void SetBuffer(int index, ReadOnlyMemory<byte> buffer)
{
MemoryHandle handle = buffer.Pin();

_handles[index] = handle;
_buffers[index].Buffer = (byte*)handle.Pointer;
_buffers[index].Length = (uint)buffer.Length;
}

/// <summary>
/// The method initializes QUIC_BUFFER* with data from inputs, converted via toBuffer.
/// Initializes QUIC_BUFFER* with data from inputs, converted via toBuffer.
/// Note that the struct either needs to be freshly created via new or previously cleaned up with Reset.
/// </summary>
/// <param name="inputs">Inputs to get their byte array, pin them and pepare them to be passed to MsQuic as QUIC_BUFFER*.</param>
/// <param name="toBuffer">Method extracting byte array from the inputs, e.g. applicationProtocol.Protocol.</param>
/// <typeparam name="T">The type of the inputs.</typeparam>
public void Initialize<T>(IList<T> inputs, Func<T, ReadOnlyMemory<byte>> toBuffer)
{
if (_handles.Length < inputs.Count)
Reserve(inputs.Count);

for (int i = 0; i < inputs.Count; ++i)
{
ReadOnlyMemory<byte> buffer = toBuffer(inputs[i]);
SetBuffer(i, buffer);
}
}

/// <summary>
/// Initializes QUIC_BUFFER* with the provided buffer.
/// Note that the struct either needs to be freshly created via new or previously cleaned up with Reset.
/// </summary>
/// <param name="buffer">Buffer to be passed to MsQuic as QUIC_BUFFER*.</param>
public void Initialize(ReadOnlyMemory<byte> buffer)
{
Reserve(1);
SetBuffer(0, buffer);
}

/// <summary>
/// Initializes QUIC_BUFFER* with the provided buffers.
/// Note that the struct either needs to be freshly created via new or previously cleaned up with Reset.
/// </summary>
/// <param name="buffers">Buffers to be passed to MsQuic as QUIC_BUFFER*.</param>
public void Initialize(ReadOnlySequence<byte> buffers)
{
int count = 0;
foreach (ReadOnlyMemory<byte> _ in buffers)
{
_handles = new MemoryHandle[inputs.Count];
++count;
}
if (_count < inputs.Count)

Reserve(count);
int i = 0;
foreach (ReadOnlyMemory<byte> buffer in buffers)
{
FreeNativeMemory();
_buffers = (QUIC_BUFFER*)NativeMemory.Alloc((nuint)sizeof(QUIC_BUFFER), (nuint)inputs.Count);
SetBuffer(i++, buffer);
}
}

_count = inputs.Count;
/// <summary>
/// Initializes QUIC_BUFFER* with the provided buffers.
/// Note that the struct either needs to be freshly created via new or previously cleaned up with Reset.
/// </summary>
/// <param name="buffers">Buffers to be passed to MsQuic as QUIC_BUFFER*.</param>
public void Initialize(ReadOnlyMemory<ReadOnlyMemory<byte>> buffers)
{
int count = buffers.Length;
Reserve(count);

for (int i = 0; i < inputs.Count; ++i)
ReadOnlySpan<ReadOnlyMemory<byte>> span = buffers.Span;
for (int i = 0; i < span.Length; i++)
{
ReadOnlyMemory<byte> buffer = toBuffer(inputs[i]);
MemoryHandle handle = buffer.Pin();

_handles[i] = handle;
_buffers[i].Buffer = (byte*)handle.Pointer;
_buffers[i].Length = (uint)buffer.Length;
SetBuffer(i, span[i]);
}
}

Expand Down
Loading

0 comments on commit fff4ff0

Please sign in to comment.