-
Notifications
You must be signed in to change notification settings - Fork 899
Native loading: simplify git_libgit2_init
/ git_libgit2_shutdown
#1438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it should effectively fix #1436
LibGit2Sharp/Core/NativeMethods.cs
Outdated
/// </summary> | ||
private sealed class LibraryLifetimeObject : CriticalFinalizerObject | ||
private static readonly NativeShutdownObject shutdownObject; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You no longer restore this warning. Was that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was not - thank you for catching this.
ff3062b
to
1764878
Compare
BTW this creates a merge conflict with #1318 so once you merge I'll do the best I can to resolve the conflict and update that PR, but please consider reviewing the merge commit to make sure I kept what you are trying to do here. |
Yeah - I feel like everything's going to create a merge conflict with #1318. 😛 I'm perfectly happy to wait on this until #1318 lands and deal with the merge conflicts myself - and I feel like we're very, very close to seeing #1318 land. Since you were the motivation behind this PR, I'm going to say that it's really up to you. |
I'm willing to go either way, but I guess it's easier for me if you hold off on merging this till #1318 is done. Thanks. |
Will do - thanks @AArnott ! |
1764878
to
e6ef3da
Compare
Remove the refcounting of libgit2 usage leftover from when `SafeHandleBase` ensured that all handles were finished before calling `git_libgit2_shutdown`. libgit2 itself does this refcounting now, we no longer need to. We only need to call `git_libgit2_init` before the first call to libgit2 and `git_libgit2_shutdown` at the end.
Only set up the object with the `git_libgit2_shutdown` finalizer when `git_libgit2_init` has succeeded. This ensures that setting up the finalizer is the last thing that we do in the static constructor for `NativeMethods`, meaning that any exception trying to p/invoke `git_libgit2_init` remains catch-able.
.NET Core no longer supports CriticalFinalizerObject. We now get the strictest finalization guarantees simply inheriting Object. See https://github.com/dotnet/corefx/issues/1345
e6ef3da
to
b21e2f9
Compare
Move the
git_libgit2_init
call out of the object that contains the finalizer that does the correspondinggit_libgit2_shutdown
. We do not want to create the object with that finalizer until we are sure that libgit2 has been loaded.Otherwise, that finalizer will be called even when the constructor threw an exception (probably from
git_libgit2_init
not finding the native library). In this case, when the finalizer is invoked, it will rethrow theTypeInitializationException
, and exceptions from finalizers are not catchable.By ensuring that the object with the finalizer is only created after
git_libgit2_init
succeeds, then we can ensure that any failures ingit_libgit2_init
remain catchable.Now that our object's lifecycle ensures that we must have called
git_libgit2_init
in order for it to have been created, we can remove the unnecessary reference counting logic. We previously refcounted the native methods, with eachSafeHandleBase
updating that reference count, so that we did not callgit_libgit2_shutdown
before we were finished with the safe handle. But this is obsolete, and this refcounting was unused outside of the load / unload scenario. So we can simply do the unload in the finalizer, without trying to do any unnecessary work on the refcount.