Skip to content

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

Merged
merged 4 commits into from
Jun 24, 2017

Conversation

ethomson
Copy link
Member

Move the git_libgit2_init call out of the object that contains the finalizer that does the corresponding git_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 the TypeInitializationException, 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 in git_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 each SafeHandleBase updating that reference count, so that we did not call git_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.

@ethomson
Copy link
Member Author

/cc @AArnott @whoisj

Copy link
Contributor

@AArnott AArnott left a 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

/// </summary>
private sealed class LibraryLifetimeObject : CriticalFinalizerObject
private static readonly NativeShutdownObject shutdownObject;

Copy link
Contributor

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?

Copy link
Member Author

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.

@ethomson ethomson force-pushed the ethomson/native_load branch from ff3062b to 1764878 Compare April 18, 2017 14:53
@AArnott
Copy link
Contributor

AArnott commented Apr 18, 2017

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.

@ethomson
Copy link
Member Author

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.

@AArnott
Copy link
Contributor

AArnott commented Apr 18, 2017

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.

@ethomson
Copy link
Member Author

Will do - thanks @AArnott !

ethomson added 3 commits June 24, 2017 15:44
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
@ethomson ethomson force-pushed the ethomson/native_load branch from e6ef3da to b21e2f9 Compare June 24, 2017 14:52
@ethomson ethomson merged commit aa6a7e2 into master Jun 24, 2017
@ethomson ethomson deleted the ethomson/native_load branch February 15, 2019 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants