8000 Decorrelate IDisposable implementation from freeing of OdbBackend res… · apfunk/libgit2sharp@ed3eda0 · GitHub
[go: up one dir, main page]

Skip to content

Commit ed3eda0

Browse files
committed
Decorrelate IDisposable implementation from freeing of OdbBackend resources
1 parent 5dcf507 commit ed3eda0

File tree

3 files changed

+66
-7
lines changed

3 files changed

+66
-7
lines changed

LibGit2Sharp.Tests/OdbBackendFixture.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,48 @@ private static Blob CreateBlob(Repository repo, string content)
221221
}
222222
}
223223

224+
[Fact]
225+
public void ADisposableOdbBackendGetsDisposedUponRepositoryDisposal()
226+
{
227+
string path = InitNewRepository();
228+
229+
int nbOfDisposeCalls = 0;
230+
231+
using (var repo = new Repository(path))
232+
{
233+
var mockOdbBackend = new MockOdbBackend(() => { nbOfDisposeCalls++; });
234+
235+
Assert.IsAssi 8000 gnableFrom<IDisposable>(mockOdbBackend);
236+
237+
repo.ObjectDatabase.AddBackend(mockOdbBackend, 5);
238+
239+
Assert.Equal(0, nbOfDisposeCalls);
240+
}
241+
242+
Assert.Equal(1, nbOfDisposeCalls);
243+
}
244+
224245
#region MockOdbBackend
225246

226-
private class MockOdbBackend : OdbBackend
247+
private class MockOdbBackend : OdbBackend, IDisposable
227248
{
249+
public MockOdbBackend(Action disposer = null)
250+
{
251+
this.disposer = disposer;
252+
}
253+
254+
public void Dispose()
255+
{
256+
if (disposer == null)
257+
{
258+
return;
259+
}
260+
261+
disposer();
262+
263+
disposer = null;
264+
}
265+
228266
protected override OdbBackendOperations SupportedOperations
229267
{
230268
get
@@ -398,6 +436,8 @@ public override int ReadHeader(ObjectId oid, out int length, out ObjectType obje
398436
private readonly Dictionary<ObjectId, MockGitObject> m_objectIdToContent =
399437
new Dictionary<ObjectId, MockGitObject>();
400438

439+
private Action disposer;
440+
401441
#region Unimplemented
402442

403443
public override int ReadStream(ObjectId oid, out OdbBackendStream stream)

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ public virtual Blob CreateBlob(string path)
9999

100100
/// <summary>
101101
/// Adds the provided backend to the object database with the specified priority.
102+
/// <para>
103+
/// If the provided backend implements <see cref="IDisposable"/>, the <see cref="IDisposable.Dispose"/>
104+
/// method will be honored and invoked upon the disposal of the repository.
105+
/// </para>
102106
/// </summary>
103107
/// <param name="backend">The backend to add</param>
104108
/// <param name="priority">The priority at which libgit2 should consult this backend (higher values are consulted first)</param>

LibGit2Sharp/OdbBackend.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,26 @@ namespace LibGit2Sharp
88
{
99
/// <summary>
1010
/// Base class for all custom managed backends for the libgit2 object database (ODB).
11+
/// <para>
12+
/// If the derived backend implements <see cref="IDisposable"/>, the <see cref="IDisposable.Dispose"/>
13+
/// method will be honored and invoked upon the disposal of the repository.
14+
/// </para>
1115
/// </summary>
1216
public abstract class OdbBackend
1317
{
1418
/// <summary>
1519
/// Invoked by libgit2 when this backend is no longer needed.
1620
/// </summary>
17-
protected virtual void Dispose()
21+
internal void Free()
1822
{
19-
if (IntPtr.Zero != nativeBackendPointer)
23+
if (nativeBackendPointer == IntPtr.Zero)
2024
{
21-
GCHandle.FromIntPtr(Marshal.ReadIntPtr(nativeBackendPointer, GitOdbBackend.GCHandleOffset)).Free();
22-
Marshal.FreeHGlobal(nativeBackendPointer);
23-
nativeBackendPointer = IntPtr.Zero;
25+
return;
2426
}
27+
28+
GCHandle.FromIntPtr(Marshal.ReadIntPtr(nativeBackendPointer, GitOdbBackend.GCHandleOffset)).Free();
29+
Marshal.FreeHGlobal(nativeBackendPointer);
30+
nativeBackendPointer = IntPtr.Zero;
2531
}
2632

2733
/// <summary>
@@ -588,7 +594,16 @@ private static void Free(
588594

589595
try
590596
{
591-
odbBackend.Dispose();
597+
odbBackend.Free();
598+
599+
var disposable = odbBackend as IDisposable;
600+
601+
if (disposable == null)
602+
{
603+
return;
604+
}
605+
606+
disposable.Dispose();
592607
}
593608
catch (Exception ex)
594609
{

0 commit comments

Comments
 (0)
0