Skip to content

Commit

Permalink
Fix overflow error in ReturnBlocks (#187)
Browse files Browse the repository at this point in the history
* Fix overflow error in ReturnBlocks

* Check for underflow/overflow in debug builds

Co-authored-by: Ben Watson <[email protected]>
  • Loading branch information
benmwatson and Ben Watson authored Jul 22, 2021
1 parent 14e2f52 commit 5b0ce2d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
29 changes: 29 additions & 0 deletions UnitTests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3384,6 +3384,35 @@ private RecyclableMemoryStream GetRandomStream()
}
#endregion

#region Bug Reports
// Issue #176 - SmallPoolInUseSize, SmallPoolFreeSize
[Test]
public void Issue176_PoolInUseSizeDoesNotDecrease()
{
long maximumFreeSmallPoolBytes = 32000L * 128000; //4096000000
long maximumFreeLargePoolBytes = UInt32.MaxValue;
int blockSize = 128000;

var mgr = new RecyclableMemoryStreamManager(blockSize, 1<<20, 8 * (1<<20),
maximumFreeSmallPoolBytes, maximumFreeLargePoolBytes);

MemoryStream fillStream = mgr.GetStream("pool", requiredSize: 128000, asContiguousBuffer: true);
byte[] block1 = new byte[128000];
long test1 = 4096000000;
int test2 = 128000;
for (int i = 0; i < 32000; i++)
{
fillStream.Write(block1, 0, 128000);
test1 -= test2;
}

Assert.That(test1, Is.EqualTo(0));
Assert.That(mgr.SmallPoolInUseSize, Is.EqualTo(maximumFreeSmallPoolBytes));
fillStream.Dispose();
Assert.That(mgr.SmallPoolInUseSize, Is.EqualTo(0));
}
#endregion

protected abstract bool AggressiveBufferRelease { get; }

protected virtual bool UseExponentialLargeBuffer
Expand Down
1 change: 1 addition & 0 deletions UnitTests/UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<AssemblyName>Microsoft.IO.RecyclableMemoryStream.UnitTests</AssemblyName>
<TargetFramework>net5.0</TargetFramework>
<DebugType>Full</DebugType> <!-- NUnit in VS2017 needs this instead of the new slimmer PDBs -->
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nunit" Version="3.13.2" />
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.IO.RecyclableMemoryStream.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<PackageProjectUrl>https://github.com/Microsoft/Microsoft.IO.RecyclableMemoryStream</PackageProjectUrl>
<IncludeBuildOutput>true</IncludeBuildOutput>
<LangVersion>9.0</LangVersion>
<CheckForOverflowUnderflow Condition="'$(Configuration)' == 'Debug'">true</CheckForOverflowUnderflow>
</PropertyGroup>
<!-- for assembly signing we use a magic variable coupled with a special build definition which skips UTs -->
<PropertyGroup Condition="'$(SignedBuild)' == 'true'">
Expand Down
2 changes: 1 addition & 1 deletion src/RecyclableMemoryStreamManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ internal void ReturnBlocks(ICollection<byte[]> blocks, Guid id, string tag)
throw new ArgumentNullException(nameof(blocks));
}

var bytesToReturn = blocks.Count * this.BlockSize;
long bytesToReturn = (long)blocks.Count * (long)this.BlockSize;
Interlocked.Add(ref this.smallPoolInUseSize, -bytesToReturn);

foreach (var block in blocks)
Expand Down

0 comments on commit 5b0ce2d

Please sign in to comment.