Lock during finalizer to not race with dispose in MemoryPoolBlock (#9555)
This commit is contained in:
parent
5f3bdba584
commit
87229e315e
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -42,11 +42,7 @@ namespace System.Buffers
|
|||
|
||||
~MemoryPoolBlock()
|
||||
{
|
||||
if (Slab != null && Slab.IsActive)
|
||||
{
|
||||
// Need to make a new object because this one is being finalized
|
||||
Pool.Return(new MemoryPoolBlock(Pool, Slab, _offset, _length));
|
||||
}
|
||||
Pool.RefreshBlock(Slab, _offset, _length);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -58,4 +54,4 @@ namespace System.Buffers
|
|||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,6 +160,21 @@ namespace System.Buffers
|
|||
}
|
||||
}
|
||||
|
||||
// This method can ONLY be called from the finalizer of MemoryPoolBlock
|
||||
internal void RefreshBlock(MemoryPoolSlab slab, int offset, int length)
|
||||
{
|
||||
lock (_disposeSync)
|
||||
{
|
||||
if (!_isDisposed && slab != null && slab.IsActive)
|
||||
{
|
||||
// Need to make a new object because this one is being finalized
|
||||
// Note, this must be called within the _disposeSync lock because the block
|
||||
// could be disposed at the same time as the finalizer.
|
||||
Return(new MemoryPoolBlock(this, slab, offset, length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_isDisposed)
|
||||
|
|
|
|||
Loading…
Reference in New Issue