Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 5e14e55

Browse files
committed
Finalizer asserts unpinned memory only for one-time-use blocks / Pin() Asserts repinning of unpinned blocks / Unpin() Asserts definite Pinned memory / Capitalization
1 parent 0f718ad commit 5e14e55

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolBlock2.cs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,22 @@ protected MemoryPoolBlock2()
7474
/// </summary>
7575
public MemoryPoolBlock2 Next { get; set; }
7676

77+
/// <summary>
78+
/// Finalizes this instance.
79+
/// </summary>
7780
~MemoryPoolBlock2()
7881
{
79-
Debug.Assert(!_pinHandle.IsAllocated, "Ad-hoc memory block wasn't unpinned");
80-
// Debug.Assert(Slab == null || !Slab.IsActive, "Block being garbage collected instead of returned to pool");
81-
82-
if (_pinHandle.IsAllocated)
82+
if(_pinHandle != null)
8383
{
84-
// if this is a one-time-use block, ensure that the GCHandle does not leak
85-
_pinHandle.Free();
86-
}
84+
Debug.Assert(!_pinHandle.IsAllocated, "One-time-use memory is unpinned");
8785

86+
if(_pinHandle.IsAllocated)
87+
{
88+
// TODO: Must be logged somehow.
89+
_pinHandle.Free();
90+
}
91+
}
92+
8893
if (Slab != null && Slab.IsActive)
8994
{
9095
Pool.Return(new MemoryPoolBlock2
@@ -104,17 +109,23 @@ protected MemoryPoolBlock2()
104109
/// </summary>
105110
/// <returns></returns>
106111
public IntPtr Pin()
107-
{
108-
Debug.Assert(!_pinHandle.IsAllocated);
109-
112+
{
110113
if (_dataArrayPtr != IntPtr.Zero)
111114
{
112-
// this is a slab managed block - use the native address of the slab which is always locked
115+
// This is a slab managed block - use the native address of the slab which is always locked.
113116
return _dataArrayPtr;
114117
}
115118
else
116119
{
117-
// this is one-time-use memory - lock the managed memory until Unpin is called
120+
// This block uses one-time-use memory.
121+
122+
if (_pinHandle != null)
123+
{
124+
// This block was pinned at least once.
125+
126+
Debug.Assert(!_pinHandle.IsAllocated, "One-time-use memory is unpinned");
127+
}
128+
118129
_pinHandle = GCHandle.Alloc(Data.Array, GCHandleType.Pinned);
119130
return _pinHandle.AddrOfPinnedObject();
120131
}
@@ -124,8 +135,10 @@ public void Unpin()
124135
{
125136
if (_dataArrayPtr == IntPtr.Zero)
126137
{
127-
// this is one-time-use memory - unlock the managed memory
128-
Debug.Assert(_pinHandle.IsAllocated);
138+
// This block uses one-time-use memory.
139+
140+
Debug.Assert(_pinHandle != null && _pinHandle.IsAllocated, "One-time-use memory is pinned");
141+
129142
_pinHandle.Free();
130143
}
131144
}
@@ -148,7 +161,7 @@ public static MemoryPoolBlock2 Create(
148161
}
149162

150163
/// <summary>
151-
/// called when the block is returned to the pool. mutable values are re-assigned to their guaranteed initialized state.
164+
/// Called when the block is returned to the pool. mutable values are re-assigned to their guaranteed initialized state.
152165
/// </summary>
153166
public void Reset()
154167
{
@@ -167,7 +180,7 @@ public override string ToString()
167180
}
168181

169182
/// <summary>
170-
/// acquires a cursor pointing into this block at the Start of "active" byte information
183+
/// Acquires a cursor pointing into this block at the Start of "active" byte information
171184
/// </summary>
172185
/// <returns></returns>
173186
public MemoryPoolIterator2 GetIterator()

0 commit comments

Comments
 (0)