Make some MemoryPoolBlock operations volatile
- Making MemoryPoolBlock.End volatile and using Volatile.Write for MemoryPoolBlock.Next prevents a race that could cause threads consuming blocks to skip produced bytes.
This commit is contained in:
parent
4c39374dc0
commit
12a3816c12
|
|
@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_tail.Next = _pinned;
|
Volatile.Write(ref _tail.Next, _pinned);
|
||||||
_tail = _pinned;
|
_tail = _pinned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,14 +57,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
||||||
/// the Start is guaranteed to be equal to Array.Offset. The value of Start may be assigned anywhere between Data.Offset and
|
/// the Start is guaranteed to be equal to Array.Offset. The value of Start may be assigned anywhere between Data.Offset and
|
||||||
/// Data.Offset + Data.Count, and must be equal to or less than End.
|
/// Data.Offset + Data.Count, and must be equal to or less than End.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Start { get; set; }
|
public int Start;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The End represents the offset into Array where the range of "active" bytes ends. At the point when the block is leased
|
/// The End represents the offset into Array where the range of "active" bytes ends. At the point when the block is leased
|
||||||
/// the End is guaranteed to be equal to Array.Offset. The value of Start may be assigned anywhere between Data.Offset and
|
/// the End is guaranteed to be equal to Array.Offset. The value of Start may be assigned anywhere between Data.Offset and
|
||||||
/// Data.Offset + Data.Count, and must be equal to or less than End.
|
/// Data.Offset + Data.Count, and must be equal to or less than End.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int End { get; set; }
|
public volatile int End;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reference to the next block of data when the overall "active" bytes spans multiple blocks. At the point when the block is
|
/// Reference to the next block of data when the overall "active" bytes spans multiple blocks. At the point when the block is
|
||||||
|
|
@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
||||||
/// working memory. The "active" memory is grown when bytes are copied in, End is increased, and Next is assigned. The "active"
|
/// working memory. The "active" memory is grown when bytes are copied in, End is increased, and Next is assigned. The "active"
|
||||||
/// memory is shrunk when bytes are consumed, Start is increased, and blocks are returned to the pool.
|
/// memory is shrunk when bytes are consumed, Start is increased, and blocks are returned to the pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MemoryPoolBlock Next { get; set; }
|
public MemoryPoolBlock Next;
|
||||||
|
|
||||||
~MemoryPoolBlock()
|
~MemoryPoolBlock()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
||||||
{
|
{
|
||||||
|
|
@ -767,7 +768,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
||||||
{
|
{
|
||||||
var nextBlock = pool.Lease();
|
var nextBlock = pool.Lease();
|
||||||
block.End = blockIndex;
|
block.End = blockIndex;
|
||||||
block.Next = nextBlock;
|
Volatile.Write(ref block.Next, nextBlock);
|
||||||
block = nextBlock;
|
block = nextBlock;
|
||||||
|
|
||||||
blockIndex = block.Data.Offset;
|
blockIndex = block.Data.Offset;
|
||||||
|
|
@ -820,7 +821,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
||||||
{
|
{
|
||||||
var nextBlock = pool.Lease();
|
var nextBlock = pool.Lease();
|
||||||
block.End = blockIndex;
|
block.End = blockIndex;
|
||||||
block.Next = nextBlock;
|
Volatile.Write(ref block.Next, nextBlock);
|
||||||
block = nextBlock;
|
block = nextBlock;
|
||||||
|
|
||||||
blockIndex = block.Data.Offset;
|
blockIndex = block.Data.Offset;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue