-
Notifications
You must be signed in to change notification settings - Fork 899
Call git_threads_shutdown() after last handle get disposed #358
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
If you have separate |
Also, you should only call The runtime ensures this is only called once, where |
Your call to |
Thanks, it is my first time with Interlocked. Omitting bugy imple 8000 mentation, do you think it is an acceptable solution? |
Do we care about the |
"The last one turns off the light" -> This sure looks like an interesting proposal. /cc @xpaulbettsx @phkelley |
@jamill No, the finalization process for those handles never makes any calls into libgit2. |
@sharwell correct - but with the current implementation here, they are still included in the handle counting (unless I am mistaken). |
The runtime will not call |
NotOwnedSafeHandle inherits from SafeHandle |
Thanks - I missed that originally, I was mistaken - my apolgies. |
Since
The concern at that point is what the P/Invoke layer does when a method returns the handle 0 - it will still construct the |
I would introduce new abstract function IsReleasable(). |
It already exists as |
Yes but it can not be used to determine whether AddHandle or not. Maybe IsReleasable is not a good name. I meant that I would introduce a new function that will tell if AddHandle/RemoveHandle should be called. |
You can delay the call to This is based on the following documentation: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.releasehandle.aspx
|
Can you guarantee that invalid handle never becomes valid? |
As I am not familiar with libgit handles: Can a valid handle becomes invalid? |
I would prefer to call RemoveHandle from Dispose, ensuring it is called only once. |
Yes, someone could call
|
Yes, but I can check if this is the first call to Dispose and only in that case call RemoveHandle |
…dle will eventually be called)
I sent you a pull request to cover the |
As we can not assume that handle does not become valid after ~LibraryLifetimeObject was called I consider IsInvalid approach as unsafe. I pushed other proposal which unregisters handle from both finalizer and dispose. |
My modified approach (the pull request yesterday) handles the case you refer to.
|
What will happen when I call IsInvalid before it becomes valid? |
That would require calling Edit: Or a derived type manipulating the value of protected field |
|
How is this going to happen? |
Newly created SafeHandleBase is invalid. Then it becomes valid when its handle value becomes non zero. |
|
But IsInvalid is public and can be called at any time. If you add an assert that invalid handle never becomes valid after IsInvalid was called then I accept your solution. |
I'm about to send you a pull request with a "special" assertion that's safe for execution at this point in the application shutdown process, plus better documentation and a couple small tweaks. |
It automatically updated the previous pull request (now there are a total of 4 commits in it) |
@sharwell I think your solution is 99.9% safe. It fails only when one uses handle in unusual way. My solution uses the same technique as LibraryLifetimeObject and it is resistant to cases that your solution is not. As you know this project and handles better, let me know if you see any weak points in my solution. |
What exactly do you define as "failure"? Currently I don't see any cases where yours handles a situation that mine does not.
|
Your use of a finalizer is a big problem as well. See C# - What does “destructors are not inherited” actually mean?. In your implementation, if a |
Thanks, I removed finalizer - it is unneccessary (and badly used as you noticed) since
Since |
There is no requirement that the CLR implement critical finalization of I believe the limitations on the use of |
I see that regular case is to obtain a handle from native method. I thought that handle can be set by external code but this would be very unusual to expose handle to public scope. Thanks, I learnt a lot. |
At this point I think we have a pretty solid solution worked out. Thanks for working through this with me 👍 |
Guys, this is an awesome collaboration! Could you please consider squashing those commits altogether? |
{ | ||
int count = Interlocked.Decrement(ref handlesCount); | ||
if (count == 0) | ||
git_threads_shutdown(); |
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.
Nitpick: Could you please surround this statement with braces?
@sharwell As the most of the code comes from you, could you please squash it to one commit and create a new pull request? |
Implementation for #249 (comment)