Avoid potential problems if Return were to throw an exception after having already put the array back into the pool.
}
ClearHelper();
- ArrayPool<byte>.Shared.Return(_rentedBuffer);
+ byte[] toReturn = _rentedBuffer;
_rentedBuffer = null!;
+ ArrayPool<byte>.Shared.Return(toReturn);
}
public void Advance(int count)
filePath.CopyTo(0, buffer, 0, filePath.Length);
buffer[filePath.Length] = '\0';
+ IntPtr hIcon;
fixed (char* b = buffer)
{
- IntPtr hIcon = Interop.Shell32.ExtractAssociatedIcon(NativeMethods.NullHandleRef, b, ref index);
- ArrayPool<char>.Shared.Return(buffer);
- if (hIcon != IntPtr.Zero)
- {
- return new Icon(hIcon, true);
- }
+ hIcon = Interop.Shell32.ExtractAssociatedIcon(NativeMethods.NullHandleRef, b, ref index);
+ }
+
+ ArrayPool<char>.Shared.Return(buffer);
+
+ if (hIcon != IntPtr.Zero)
+ {
+ return new Icon(hIcon, true);
}
return null;
{
_disposed = true;
- Debug.Assert(_charBuffer.Array != null);
- ArrayPool<char>.Shared.Return(_charBuffer.Array);
+ char[]? charBuffer = _charBuffer.Array;
+ Debug.Assert(charBuffer != null);
_charBuffer = default;
+ ArrayPool<char>.Shared.Return(charBuffer);
- Debug.Assert(_byteBuffer.Array != null);
- ArrayPool<byte>.Shared.Return(_byteBuffer.Array);
+ byte[]? byteBuffer = _byteBuffer.Array;
+ Debug.Assert(byteBuffer != null);
_byteBuffer = default;
+ ArrayPool<byte>.Shared.Return(byteBuffer);
- Debug.Assert(_overflowBuffer.Array != null);
- ArrayPool<byte>.Shared.Return(_overflowBuffer.Array);
+ byte[]? overflowBuffer = _overflowBuffer.Array;
+ Debug.Assert(overflowBuffer != null);
_overflowBuffer = default;
+ ArrayPool<byte>.Shared.Return(overflowBuffer);
_stream.Dispose();
}
if (!_disposed)
{
_disposed = true;
- ArrayPool<char>.Shared.Return(_charBuffer);
+ char[] toReturn = _charBuffer;
_charBuffer = null!;
+ ArrayPool<char>.Shared.Return(toReturn);
}
}
if (status.ErrorCode == SecurityStatusPalErrorCode.TryAgain)
{
// No need to hold on the buffer any more.
- ArrayPool<byte>.Shared.Return(bufferToReturn);
+ byte[] tmp = bufferToReturn;
bufferToReturn = null;
+ ArrayPool<byte>.Shared.Return(tmp);
+
// Call WriteSingleChunk() recursively to avoid code duplication.
// This should be extremely rare in cases when second renegotiation happens concurrently with Write.
await WriteSingleChunk(writeAdapter, buffer).ConfigureAwait(false);
// actually contains no decrypted or encrypted bytes
private void ReturnReadBufferIfEmpty()
{
- if (_internalBuffer != null && _decryptedBytesCount == 0 && _internalBufferCount == 0)
+ if (_internalBuffer is byte[] internalBuffer && _decryptedBytesCount == 0 && _internalBufferCount == 0)
{
- ArrayPool<byte>.Shared.Return(_internalBuffer);
_internalBuffer = null;
- _internalBufferCount = 0;
_internalOffset = 0;
- _decryptedBytesCount = 0;
_decryptedBytesOffset = 0;
+ ArrayPool<byte>.Shared.Return(internalBuffer);
}
else if (_decryptedBytesCount == 0)
{
{
public struct DataSegment
{
- private readonly byte[] _buffer;
+ private byte[] _buffer;
public DataSegment(int length)
{
public Span<byte> AsSpan() => new Span<byte>(_buffer, 0, Length);
public ulong Checksum => CRC.CalculateCRC(AsSpan());
- public void Return() => ArrayPool<byte>.Shared.Return(_buffer);
+ public void Return()
+ {
+ byte[] toReturn = _buffer;
+ _buffer = null;
+ ArrayPool<byte>.Shared.Return(toReturn);
+ }
/// Create and populate a segment with random data
public static DataSegment CreateRandom(Random random, int maxLength)
public void ReleaseBuffer()
{
- if (_buffer is not null)
+ if (_buffer is byte[] toReturn)
{
- ArrayPool<byte>.Shared.Return(_buffer);
_buffer = null;
+ ArrayPool<byte>.Shared.Return(toReturn);
}
}
// Rent a 30% bigger buffer
byte[] newBuffer = ArrayPool<byte>.Shared.Rent((int)(_buffer.Length * 1.3));
_buffer.AsSpan(0, position).CopyTo(newBuffer);
- ArrayPool<byte>.Shared.Return(_buffer);
+
+ byte[] toReturn = _buffer;
_buffer = newBuffer;
+
+ ArrayPool<byte>.Shared.Return(toReturn);
}
return new ReadOnlySpan<byte>(_buffer, 0, position);
{
byte[] newBuffer = ArrayPool<byte>.Shared.Rent(_available + FlushMarkerLength);
_buffer.AsSpan(0, _available).CopyTo(newBuffer);
- ArrayPool<byte>.Shared.Return(_buffer);
+ byte[] toReturn = _buffer;
_buffer = newBuffer;
+
+ ArrayPool<byte>.Shared.Return(toReturn);
}
FlushMarker.CopyTo(_buffer.AsSpan(_available));
private void ReleaseBuffer()
{
- if (_buffer is not null)
+ if (_buffer is byte[] toReturn)
{
- ArrayPool<byte>.Shared.Return(_buffer);
_buffer = null;
_available = 0;
_position = 0;
+
+ ArrayPool<byte>.Shared.Return(toReturn);
}
}
{
Debug.Assert(_sendFrameAsyncLock.CurrentCount == 0, "Caller should hold the _sendFrameAsyncLock");
- byte[]? old = _sendBuffer;
- if (old != null)
+ if (_sendBuffer is byte[] toReturn)
{
_sendBuffer = null;
- ArrayPool<byte>.Shared.Return(old);
+ ArrayPool<byte>.Shared.Return(toReturn);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
- if (_arrayFromPool != null)
+ T[]? toReturn = _arrayFromPool;
+ if (toReturn != null)
{
- ArrayPool<T>.Shared.Return(_arrayFromPool);
_arrayFromPool = null;
+ ArrayPool<T>.Shared.Return(toReturn);
}
}
CloseDirectoryHandle();
- if (_pathBuffer != null)
- ArrayPool<char>.Shared.Return(_pathBuffer);
- _pathBuffer = null;
- if (_entryBuffer != null)
- ArrayPool<byte>.Shared.Return(_entryBuffer);
- _entryBuffer = null;
+ if (_pathBuffer is char[] pathBuffer)
+ {
+ _pathBuffer = null;
+ ArrayPool<char>.Shared.Return(pathBuffer);
+ }
+
+ if (_entryBuffer is byte[] entryBuffer)
+ {
+ _entryBuffer = null;
+ ArrayPool<byte>.Shared.Return(entryBuffer);
+ }
}
}
byte[] tmp = ArrayPool<byte>.Shared.Rent((int)newLength);
Buffer.BlockCopy(rentedArray, 0, tmp, 0, bytesRead);
- ArrayPool<byte>.Shared.Return(rentedArray);
+
+ byte[] toReturn = rentedArray;
rentedArray = tmp;
+
+ ArrayPool<byte>.Shared.Return(toReturn);
}
Debug.Assert(bytesRead < rentedArray.Length);
// the return value is the required buffer size, in TCHARs. This value includes the size of the terminating null character.
if (result > buffer.Length)
{
- ArrayPool<char>.Shared.Return(buffer);
+ char[] toReturn = buffer;
buffer = ArrayPool<char>.Shared.Rent((int)result);
+ ArrayPool<char>.Shared.Return(toReturn);
result = GetFinalPathNameByHandle(handle, buffer);
}
List<string>? toExplore = null; // List used as a stack
int bufferSize = Interop.Sys.GetReadDirRBufferSize();
- byte[]? dirBuffer = null;
+ byte[] dirBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
try
{
- dirBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
string currentPath = path;
fixed (byte* dirBufferPtr = dirBuffer)
}
finally
{
- if (dirBuffer != null)
- ArrayPool<byte>.Shared.Return(dirBuffer);
+ ArrayPool<byte>.Shared.Return(dirBuffer);
}
}
else
{
// Use ArrayPool.Shared instead of CryptoPool because the array is passed out.
- byte[] rentedBuffer = ArrayPool<byte>.Shared.Rent(inputBuffer.Length);
+ byte[]? rentedBuffer = ArrayPool<byte>.Shared.Rent(inputBuffer.Length);
int result = default;
// Pin the rented buffer for security.
}
ArrayPool<byte>.Shared.Return(rentedBuffer);
- rentedBuffer = null!;
+ rentedBuffer = null;
return result;
}
}
CheckCopyToArguments(destination, bufferSize);
// Use ArrayPool<byte>.Shared instead of CryptoPool because the array is passed out.
- byte[] rentedBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
+ byte[]? rentedBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
// Pin the array for security.
fixed (byte* _ = &rentedBuffer[0])
{
}
}
ArrayPool<byte>.Shared.Return(rentedBuffer);
- rentedBuffer = null!;
+ rentedBuffer = null;
}
/// <inheritdoc/>
private async Task CopyToAsyncInternal(Stream destination, int bufferSize, CancellationToken cancellationToken)
{
// Use ArrayPool<byte>.Shared instead of CryptoPool because the array is passed out.
- byte[] rentedBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
+ byte[]? rentedBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
// Pin the array for security.
GCHandle pinHandle = GCHandle.Alloc(rentedBuffer, GCHandleType.Pinned);
try
pinHandle.Free();
}
ArrayPool<byte>.Shared.Return(rentedBuffer);
- rentedBuffer = null!;
+ rentedBuffer = null;
}
private void CheckCopyToArguments(Stream destination, int bufferSize)
if (contentType == DecryptedSentinel)
{
ReadOnlyMemory<byte> content = rentedContents[i].Content;
+ rentedContents[i].Content = default;
if (!MemoryMarshal.TryGetArray(content, out ArraySegment<byte> segment))
{
}
CryptoPool.Return(segment);
- rentedContents[0].Content = default;
}
}
X509ContentType.Pkcs7;
bool cont = derCallback(certBytes.AsSpan(0, bytesWritten), contentType);
- CryptoPool.Return(certBytes, clearSize: 0);
+ byte[] toReturn = certBytes;
certBytes = null;
+ CryptoPool.Return(toReturn, clearSize: 0);
if (!cont)
{
protected override object CreateObject(ref ReadStackFrame frame)
{
object[] arguments = (object[])frame.CtorArgumentState!.Arguments;
+ frame.CtorArgumentState.Arguments = null!;
var createObject = (JsonTypeInfo.ParameterizedConstructorDelegate<T>?)frame.JsonTypeInfo.CreateObjectWithArgs;
ReadPropertyValue(obj, ref state, ref tempReader, jsonPropertyInfo, useExtensionProperty);
}
- ArrayPool<FoundProperty>.Shared.Return(argumentState.FoundProperties!, clearArray: true);
+ FoundProperty[] toReturn = argumentState.FoundProperties!;
argumentState.FoundProperties = null;
+ ArrayPool<FoundProperty>.Shared.Return(toReturn, clearArray: true);
}
}
else
}
}
- ArrayPool<FoundPropertyAsync>.Shared.Return(argumentState.FoundPropertiesAsync!, clearArray: true);
+ FoundPropertyAsync[] toReturn = argumentState.FoundPropertiesAsync!;
argumentState.FoundPropertiesAsync = null;
+ ArrayPool<FoundPropertyAsync>.Shared.Return(toReturn, clearArray: true);
}
}
argumentState.FoundProperties.CopyTo(newCache, 0);
- ArrayPool<FoundProperty>.Shared.Return(argumentState.FoundProperties, clearArray: true);
-
+ FoundProperty[] toReturn = argumentState.FoundProperties;
argumentState.FoundProperties = newCache!;
+
+ ArrayPool<FoundProperty>.Shared.Return(toReturn, clearArray: true);
}
argumentState.FoundProperties[argumentState.FoundPropertyCount++] = (
argumentState.FoundPropertiesAsync!.CopyTo(newCache, 0);
- ArrayPool<FoundPropertyAsync>.Shared.Return(argumentState.FoundPropertiesAsync!, clearArray: true);
-
+ FoundPropertyAsync[] toReturn = argumentState.FoundPropertiesAsync!;
argumentState.FoundPropertiesAsync = newCache!;
+
+ ArrayPool<FoundPropertyAsync>.Shared.Return(toReturn, clearArray: true);
}
// Cache the property name and value.
{
// Clear only what we used and return the buffer to the pool
new Span<byte>(Buffer, 0, ClearMax).Clear();
- ArrayPool<byte>.Shared.Return(Buffer);
+
+ byte[] toReturn = Buffer;
Buffer = null!;
+
+ ArrayPool<byte>.Shared.Return(toReturn);
}
}
}