Skip to content
Prev Previous commit
Next Next commit
Delay allocating native memory.
  • Loading branch information
teo-tsirpanis committed Aug 31, 2021
commit 8177b2329f92f7f0a81b16d38886ec52997c893c
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,7 @@ private static unsafe bool TryPrepareScatterGatherBuffers<T, THandler>(IReadOnly
segmentsPtr = IntPtr.Zero;
totalBytes = 0;

// "The array must contain enough elements to store nNumberOfBytesToWrite bytes of data, and one element for the terminating NULL. "
long* segments = (long*) NativeMemory.Alloc((nuint)(buffersCount + 1), sizeof(long));
segments[buffersCount] = 0;
long* segments = null;

bool success = false;
try
Expand All @@ -471,18 +469,27 @@ private static unsafe bool TryPrepareScatterGatherBuffers<T, THandler>(IReadOnly
}

MemoryHandle handle = handler.Pin(in buffer);
long ptr = segments[i] = (long)handle.Pointer;
long ptr = (long)handle.Pointer;
if ((ptr & alignedAtPageSizeMask) != 0)
{
handle.Dispose();
return false;
}

// We avoid allocating an array if there are
// no buffers or the first one is unacceptable.
// We avoid allocations if there are no
// buffers or the first one is unacceptable.
(handlesToDispose ??= new MemoryHandle[buffersCount])[i] = handle;
if (segments == null)
{
// "The array must contain enough elements to store nNumberOfBytesToWrite
// bytes of data, and one element for the terminating NULL."
segments = (long*)NativeMemory.Alloc((nuint)(buffersCount + 1), sizeof(long));
}
segments[i] = ptr;
}

Debug.Assert(segments != null);
segments[buffersCount] = 0;
segmentsPtr = (IntPtr)segments;
totalBytes = (int)totalBytes64;
success = true;
Expand All @@ -507,7 +514,10 @@ private static unsafe void CleanupScatterGatherBuffers(MemoryHandle[]? handlesTo
}
}

NativeMemory.Free((void*) segmentsPtr);
if (segmentsPtr != IntPtr.Zero)
{
NativeMemory.Free((void*) segmentsPtr);
}
}

private static ValueTask<long> ReadScatterAtOffsetAsync(SafeFileHandle handle, IReadOnlyList<Memory<byte>> buffers,
Expand Down