Lock during finalizer to not race with dispose in MemoryPoolBlock (#9555)

This commit is contained in:
Justin Kotalik 2019-04-22 15:55:53 -07:00 committed by GitHub
parent 5f3bdba584
commit 87229e315e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 7 deletions

View File

@ -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;

View File

@ -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
{
}
}
}
}

View File

@ -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)