Skip to content

Commit a44c1fa

Browse files
authored
Merge pull request #548 from qmfrederik/fixes/dispose-housekeeping
Managed Git: .Dispose() housekeeping
2 parents 90d7e39 + 75d370f commit a44c1fa

File tree

7 files changed

+90
-2
lines changed

7 files changed

+90
-2
lines changed

src/NerdBank.GitVersioning/GitContext.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,10 @@ private protected static void FindGitPaths(string path, out string gitDirectory,
246246
}
247247
}
248248

249-
/// <inheritdoc />
249+
/// <summary>
250+
/// Disposes of native and managed resources associated by this object.
251+
/// </summary>
252+
/// <param name="disposing"><see langword="true" /> to dispose managed and native resources; <see langword="false" /> to only dispose of native resources.</param>
250253
protected virtual void Dispose(bool disposing)
251254
{
252255
}

src/NerdBank.GitVersioning/Managed/ManagedGitContext.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,17 @@ public override string GetShortUniqueCommitId(int minLength)
119119
return this.Repository.ShortenObjectId(this.Commit.Value.Sha, minLength);
120120
}
121121

122+
/// <inheritdoc/>
123+
protected override void Dispose(bool disposing)
124+
{
125+
if (disposing)
126+
{
127+
this.Repository.Dispose();
128+
}
129+
130+
base.Dispose(disposing);
131+
}
132+
122133
/// <summary>
123134
/// Encodes a commit from history in a <see cref="Version"/>
124135
/// so that the original commit can be found later.

src/NerdBank.GitVersioning/ManagedGit/GitPack.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ public void Dispose()
259259

260260
this.accessor.Dispose();
261261
this.packFile.Dispose();
262+
this.cache.Dispose();
262263
}
263264

264265
private long? GetOffset(GitObjectId objectId)

src/NerdBank.GitVersioning/ManagedGit/GitPackCache.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#nullable enable
22

3+
using System;
34
using System.Diagnostics.CodeAnalysis;
45
using System.IO;
56
using System.Text;
@@ -12,7 +13,7 @@ namespace Nerdbank.GitVersioning.ManagedGit
1213
/// data from a <see cref="GitPack"/> can be potentially expensive: the data is
1314
/// compressed and can be deltified.
1415
/// </summary>
15-
public abstract class GitPackCache
16+
public abstract class GitPackCache : IDisposable
1617
{
1718
/// <summary>
1819
/// Attempts to retrieve a Git object from cache.
@@ -51,5 +52,20 @@ public abstract class GitPackCache
5152
/// A <see cref="Stream"/> which represents the cached entry.
5253
/// </returns>
5354
public abstract Stream Add(long offset, Stream stream);
55+
56+
/// <inheritdoc/>
57+
public void Dispose()
58+
{
59+
this.Dispose(true);
60+
GC.SuppressFinalize(this);
61+
}
62+
63+
/// <summary>
64+
/// Disposes of native and managed resources associated by this object.
65+
/// </summary>
66+
/// <param name="disposing"><see langword="true" /> to dispose managed and native resources; <see langword="false" /> to only dispose of native resources.</param>
67+
protected virtual void Dispose(bool disposing)
68+
{
69+
}
5470
}
5571
}

src/NerdBank.GitVersioning/ManagedGit/GitPackMemoryCache.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.Diagnostics.CodeAnalysis;
55
using System.IO;
6+
using System.Linq;
67
using System.Text;
78

89
namespace Nerdbank.GitVersioning.ManagedGit
@@ -55,5 +56,22 @@ public override void GetCacheStatistics(StringBuilder builder)
5556
{
5657
builder.AppendLine($"{this.cache.Count} items in cache");
5758
}
59+
60+
/// <inheritdoc/>
61+
protected override void Dispose(bool disposing)
62+
{
63+
if (disposing)
64+
{
65+
while (this.cache.Count > 0)
66+
{
67+
var key = this.cache.Keys.First();
68+
var stream = this.cache[key];
69+
stream.Dispose();
70+
this.cache.Remove(key);
71+
}
72+
}
73+
74+
base.Dispose(disposing);
75+
}
5876
}
5977
}

src/NerdBank.GitVersioning/ManagedGit/GitPackMemoryCacheStream.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,17 @@ public override void Write(byte[] buffer, int offset, int count)
9999
throw new NotSupportedException();
100100
}
101101

102+
protected override void Dispose(bool disposing)
103+
{
104+
if (disposing)
105+
{
106+
this.stream.Dispose();
107+
this.cacheStream.Dispose();
108+
}
109+
110+
base.Dispose(disposing);
111+
}
112+
102113
private void DisposeStreamIfRead()
103114
{
104115
if (this.cacheStream.Length == this.stream.Length)

src/NerdBank.GitVersioning/ManagedGit/MemoryMappedStream.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public unsafe class MemoryMappedStream : Stream
1313
private readonly long length;
1414
private long position;
1515
private byte* ptr;
16+
private bool disposed;
1617

1718
/// <summary>
1819
/// Initializes a new instance of the <see cref="MemoryMappedStream"/> class.
@@ -57,6 +58,11 @@ public override void Flush()
5758
/// <inheritdoc/>
5859
public override int Read(byte[] buffer, int offset, int count)
5960
{
61+
if (this.disposed)
62+
{
63+
throw new ObjectDisposedException(nameof(MemoryMappedStream));
64+
}
65+
6066
int read = (int)Math.Min(count, this.length - this.position);
6167

6268
new Span<byte>(this.ptr + this.position, read)
@@ -70,6 +76,11 @@ public override int Read(byte[] buffer, int offset, int count)
7076
/// <inheritdoc/>
7177
public override int Read(Span<byte> buffer)
7278
{
79+
if (this.disposed)
80+
{
81+
throw new ObjectDisposedException(nameof(MemoryMappedStream));
82+
}
83+
7384
int read = (int)Math.Min(buffer.Length, this.length - this.position);
7485

7586
new Span<byte>(this.ptr + this.position, read)
@@ -83,6 +94,11 @@ public override int Read(Span<byte> buffer)
8394
/// <inheritdoc/>
8495
public override long Seek(long offset, SeekOrigin origin)
8596
{
97+
if (this.disposed)
98+
{
99+
throw new ObjectDisposedException(nameof(MemoryMappedStream));
100+
}
101+
86102
long newPosition = this.position;
87103

88104
switch (origin)
@@ -124,5 +140,17 @@ public override void Write(byte[] buffer, int offset, int count)
124140
{
125141
throw new NotSupportedException();
126142
}
143+
144+
/// <inheritdoc/>
145+
protected override void Dispose(bool disposing)
146+
{
147+
if (disposing)
148+
{
149+
this.accessor.SafeMemoryMappedViewHandle.ReleasePointer();
150+
this.disposed = true;
151+
}
152+
153+
base.Dispose(disposing);
154+
}
127155
}
128156
}

0 commit comments

Comments
 (0)