Skip to content

Commit bbf738f

Browse files
committed
Merge pull request libgit2#1 from sharwell/jbialobr_vNext
Only call AddHandle when we know the handle is valid
2 parents d2d5b41 + f90a967 commit bbf738f

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

LibGit2Sharp/Core/Handles/SafeHandleBase.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Diagnostics;
33
using System.Globalization;
44
using System.Runtime.InteropServices;
5+
using Interlocked = System.Threading.Interlocked;
56

67
namespace LibGit2Sharp.Core.Handles
78
{
@@ -11,10 +12,15 @@ internal abstract class SafeHandleBase : SafeHandle
1112
private readonly string trace;
1213
#endif
1314

15+
/// <summary>
16+
/// This is set to non-zero when <see cref="NativeMethods.AddHandle"/> has
17+
/// been called for this handle.
18+
/// </summary>
19+
private int registered;
20+
1421
protected SafeHandleBase()
1522
: base(IntPtr.Zero, true)
1623
{
17-
NativeMethods.AddHandle();
1824
#if LEAKS
1925
trace = new StackTrace(2, true).ToString();
2026
#endif
@@ -36,9 +42,26 @@ protected override void Dispose(bool disposing)
3642
}
3743
#endif
3844

39-
public override bool IsInvalid
45+
public override sealed bool IsInvalid
46+
{
47+
get
48+
{
49+
bool invalid = IsInvalidImpl();
50+
if (!invalid && Interlocked.CompareExchange(ref registered, 1, 0) == 0)
51+
{
52+
// Call AddHandle at most 1 time for this handle, and only after
53+
// we know that the handle is valid (i.e. ReleaseHandle will eventually
54+
// be called).
55+
NativeMethods.AddHandle();
56+
}
57+
58+
return invalid;
59+
}
60+
}
61+
62+
protected virtual bool IsInvalidImpl()
4063
{
41-
get { return (handle == IntPtr.Zero); }
64+
return handle == IntPtr.Zero;
4265
}
4366

4467
protected abstract bool ReleaseHandleImpl();

0 commit comments

Comments
 (0)