Skip to content

Commit 84dcd18

Browse files
Merge pull request #2327 from stefannikolei/stefannikolei/nullable/memory
Remove nullable disable from Memory.Allocators
2 parents ce4b49f + 9c3d68f commit 84dcd18

11 files changed

+41
-36
lines changed

src/ImageSharp/Memory/Allocators/Internals/Gen2GcCallback.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
3-
#nullable disable
43

54
// Port of BCL internal utility:
65
// https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/System.Private.CoreLib/src/System/Gen2GcCallback.cs
@@ -15,8 +14,8 @@ namespace SixLabors.ImageSharp.Memory.Internals;
1514
/// </summary>
1615
internal sealed class Gen2GcCallback : CriticalFinalizerObject
1716
{
18-
private readonly Func<bool> callback0;
19-
private readonly Func<object, bool> callback1;
17+
private readonly Func<bool>? callback0;
18+
private readonly Func<object, bool>? callback1;
2019
private GCHandle weakTargetObj;
2120

2221
private Gen2GcCallback(Func<bool> callback) => this.callback0 = callback;
@@ -32,7 +31,7 @@ private Gen2GcCallback(Func<object, bool> callback, object targetObj)
3231
if (this.weakTargetObj.IsAllocated)
3332
{
3433
// Check to see if the target object is still alive.
35-
object targetObj = this.weakTargetObj.Target;
34+
object? targetObj = this.weakTargetObj.Target;
3635
if (targetObj == null)
3736
{
3837
// The target object is dead, so this callback object is no longer needed.
@@ -43,7 +42,7 @@ private Gen2GcCallback(Func<object, bool> callback, object targetObj)
4342
// Execute the callback method.
4443
try
4544
{
46-
if (!this.callback1(targetObj))
45+
if (!this.callback1!(targetObj))
4746
{
4847
// If the callback returns false, this callback object is no longer needed.
4948
this.weakTargetObj.Free();
@@ -64,7 +63,7 @@ private Gen2GcCallback(Func<object, bool> callback, object targetObj)
6463
// Execute the callback method.
6564
try
6665
{
67-
if (!this.callback0())
66+
if (!this.callback0!())
6867
{
6968
// If the callback returns false, this callback object is no longer needed.
7069
return;

src/ImageSharp/Memory/Allocators/Internals/RefCountedMemoryLifetimeGuard.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
3-
#nullable disable
43

54
using SixLabors.ImageSharp.Diagnostics;
65

@@ -15,7 +14,7 @@ internal abstract class RefCountedMemoryLifetimeGuard : IDisposable
1514
private int refCount = 1;
1615
private int disposed;
1716
private int released;
18-
private string allocationStackTrace;
17+
private string? allocationStackTrace;
1918

2019
protected RefCountedMemoryLifetimeGuard()
2120
{

src/ImageSharp/Memory/Allocators/Internals/SharedArrayPoolBuffer{T}.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
3-
#nullable disable
43

54
using System.Buffers;
65
using System.Diagnostics;
6+
using System.Diagnostics.CodeAnalysis;
77
using System.Runtime.CompilerServices;
88
using System.Runtime.InteropServices;
99

@@ -22,7 +22,7 @@ public SharedArrayPoolBuffer(int lengthInElements)
2222
this.lifetimeGuard = new LifetimeGuard(this.Array);
2323
}
2424

25-
public byte[] Array { get; private set; }
25+
public byte[]? Array { get; private set; }
2626

2727
protected override void Dispose(bool disposing)
2828
{
@@ -41,7 +41,11 @@ public override Span<T> GetSpan()
4141
return MemoryMarshal.Cast<byte, T>(this.Array.AsSpan(0, this.lengthInBytes));
4242
}
4343

44-
protected override object GetPinnableObject() => this.Array;
44+
protected override object GetPinnableObject()
45+
{
46+
this.CheckDisposed();
47+
return this.Array;
48+
}
4549

4650
public void AddRef()
4751
{
@@ -52,6 +56,7 @@ public void AddRef()
5256
public void ReleaseRef() => this.lifetimeGuard.ReleaseRef();
5357

5458
[Conditional("DEBUG")]
59+
[MemberNotNull(nameof(Array))]
5560
private void CheckDisposed()
5661
{
5762
if (this.Array == null)
@@ -62,7 +67,7 @@ private void CheckDisposed()
6267

6368
private sealed class LifetimeGuard : RefCountedMemoryLifetimeGuard
6469
{
65-
private byte[] array;
70+
private byte[]? array;
6671

6772
public LifetimeGuard(byte[] array) => this.array = array;
6873

@@ -73,7 +78,7 @@ protected override void Release()
7378
// This is not ideal, but subsequent leaks will end up returning arrays to per-cpu buckets,
7479
// meaning likely a different bucket than it was rented from,
7580
// but this is PROBABLY better than not returning the arrays at all.
76-
ArrayPool<byte>.Shared.Return(this.array);
81+
ArrayPool<byte>.Shared.Return(this.array!);
7782
this.array = null;
7883
}
7984
}

src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
3-
#nullable disable
43

54
using System.Diagnostics;
65

@@ -13,7 +12,7 @@ internal partial class UniformUnmanagedMemoryPool : System.Runtime.ConstrainedEx
1312
{
1413
private static int minTrimPeriodMilliseconds = int.MaxValue;
1514
private static readonly List<WeakReference<UniformUnmanagedMemoryPool>> AllPools = new();
16-
private static Timer trimTimer;
15+
private static Timer? trimTimer;
1716

1817
private static readonly Stopwatch Stopwatch = Stopwatch.StartNew();
1918

@@ -97,7 +96,7 @@ public UnmanagedMemoryHandle Rent()
9796
/// <summary>
9897
/// Rent <paramref name="bufferCount"/> buffers or return 'null' if the pool is full.
9998
/// </summary>
100-
public UnmanagedMemoryHandle[] Rent(int bufferCount)
99+
public UnmanagedMemoryHandle[]? Rent(int bufferCount)
101100
{
102101
UnmanagedMemoryHandle[] buffersLocal = this.buffers;
103102

@@ -248,7 +247,7 @@ private static void TimerCallback()
248247

249248
foreach (WeakReference<UniformUnmanagedMemoryPool> weakPoolRef in AllPools)
250249
{
251-
if (weakPoolRef.TryGetTarget(out UniformUnmanagedMemoryPool pool))
250+
if (weakPoolRef.TryGetTarget(out UniformUnmanagedMemoryPool? pool))
252251
{
253252
pool.Trim();
254253
}

src/ImageSharp/Memory/Allocators/Internals/UnmanagedMemoryHandle.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
3-
#nullable disable
43

54
using System.Runtime.InteropServices;
65

@@ -20,7 +19,7 @@ internal struct UnmanagedMemoryHandle : IEquatable<UnmanagedMemoryHandle>
2019
private static long totalOomRetries;
2120

2221
// A Monitor to wait/signal when we are low on memory.
23-
private static object lowMemoryMonitor;
22+
private static object? lowMemoryMonitor;
2423

2524
public static readonly UnmanagedMemoryHandle NullHandle;
2625

@@ -114,17 +113,17 @@ public void Free()
114113
if (Volatile.Read(ref lowMemoryMonitor) != null)
115114
{
116115
// We are low on memory. Signal all threads waiting in AllocateHandle().
117-
Monitor.Enter(lowMemoryMonitor);
118-
Monitor.PulseAll(lowMemoryMonitor);
119-
Monitor.Exit(lowMemoryMonitor);
116+
Monitor.Enter(lowMemoryMonitor!);
117+
Monitor.PulseAll(lowMemoryMonitor!);
118+
Monitor.Exit(lowMemoryMonitor!);
120119
}
121120

122121
this.lengthInBytes = 0;
123122
}
124123

125124
public bool Equals(UnmanagedMemoryHandle other) => this.handle.Equals(other.handle);
126125

127-
public override bool Equals(object obj) => obj is UnmanagedMemoryHandle other && this.Equals(other);
126+
public override bool Equals(object? obj) => obj is UnmanagedMemoryHandle other && this.Equals(other);
128127

129128
public override int GetHashCode() => this.handle.GetHashCode();
130129
}

src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ internal override MemoryGroup<T> AllocateGroup<T>(
135135
}
136136

137137
// Attempt to rent the whole group from the pool, allocate a group of unmanaged buffers if the attempt fails:
138-
if (MemoryGroup<T>.TryAllocate(this.pool, totalLength, bufferAlignment, options, out MemoryGroup<T> poolGroup))
138+
if (MemoryGroup<T>.TryAllocate(this.pool, totalLength, bufferAlignment, options, out MemoryGroup<T>? poolGroup))
139139
{
140140
return poolGroup;
141141
}

src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ internal static void CopyTo<T>(this ReadOnlySpan<T> source, IMemoryGroup<T> targ
106106
}
107107
}
108108

109-
internal static void CopyTo<T>(this IMemoryGroup<T> source, IMemoryGroup<T> target)
109+
internal static void CopyTo<T>(this IMemoryGroup<T>? source, IMemoryGroup<T>? target)
110110
where T : struct
111111
{
112112
Guard.NotNull(source, nameof(source));

src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupSpanCache.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Memory;
1313
internal unsafe struct MemoryGroupSpanCache
1414
{
1515
public SpanCacheMode Mode;
16-
public byte[] SingleArray;
16+
public byte[]? SingleArray;
1717
public void* SinglePointer;
1818
public void*[] MultiPointer;
1919

src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupView{T}.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
3-
#nullable disable
43

54
using System.Buffers;
65
using System.Collections;
6+
using System.Diagnostics.CodeAnalysis;
77
using System.Runtime.CompilerServices;
88

99
namespace SixLabors.ImageSharp.Memory;
@@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Memory;
2121
internal class MemoryGroupView<T> : IMemoryGroup<T>
2222
where T : struct
2323
{
24-
private MemoryGroup<T> owner;
24+
private MemoryGroup<T>? owner;
2525
private readonly MemoryOwnerWrapper[] memoryWrappers;
2626

2727
public MemoryGroupView(MemoryGroup<T> owner)
@@ -63,6 +63,7 @@ public long TotalLength
6363
}
6464
}
6565

66+
[MemberNotNullWhen(true, nameof(owner))]
6667
public bool IsValid => this.owner != null;
6768

6869
public Memory<T> this[int index]
@@ -99,6 +100,7 @@ internal void Invalidate()
99100
this.owner = null;
100101
}
101102

103+
[MemberNotNull(nameof(owner))]
102104
private void EnsureIsValid()
103105
{
104106
if (!this.IsValid)

src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.Owned.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
3-
#nullable disable
43

54
using System.Buffers;
5+
using System.Diagnostics.CodeAnalysis;
66
using System.Runtime.CompilerServices;
77
using SixLabors.ImageSharp.Memory.Internals;
88

@@ -15,8 +15,8 @@ internal abstract partial class MemoryGroup<T>
1515
/// </summary>
1616
public sealed class Owned : MemoryGroup<T>, IEnumerable<Memory<T>>
1717
{
18-
private IMemoryOwner<T>[] memoryOwners;
19-
private RefCountedMemoryLifetimeGuard groupLifetimeGuard;
18+
private IMemoryOwner<T>[]? memoryOwners;
19+
private RefCountedMemoryLifetimeGuard? groupLifetimeGuard;
2020

2121
public Owned(IMemoryOwner<T>[] memoryOwners, int bufferLength, long totalLength, bool swappable)
2222
: base(bufferLength, totalLength)
@@ -149,7 +149,7 @@ public override void Dispose()
149149
}
150150
else
151151
{
152-
foreach (IMemoryOwner<T> memoryOwner in this.memoryOwners)
152+
foreach (IMemoryOwner<T> memoryOwner in this.memoryOwners!)
153153
{
154154
memoryOwner.Dispose();
155155
}
@@ -161,6 +161,7 @@ public override void Dispose()
161161
}
162162

163163
[MethodImpl(InliningOptions.ShortMethod)]
164+
[MemberNotNull(nameof(memoryOwners))]
164165
private void EnsureNotDisposed()
165166
{
166167
if (this.memoryOwners is null)
@@ -170,6 +171,7 @@ private void EnsureNotDisposed()
170171
}
171172

172173
[MethodImpl(MethodImplOptions.NoInlining)]
174+
[DoesNotReturn]
173175
private static void ThrowObjectDisposedException() => throw new ObjectDisposedException(nameof(MemoryGroup<T>));
174176

175177
// When the MemoryGroup points to multiple buffers via `groupLifetimeGuard`,

0 commit comments

Comments
 (0)