[2019-06] Fix issue in SafeHandle.DangerousReleaseInternal() that caused #16034.
#16424
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Using the CoreCLR version of this line fixed the problem and my investigations
also revealed why.
The
SafePipeHandlecontains a reference to both the Socket as well as theSafeSocketHandle, taking ownership of them. If there are no additionalreferences to either of them, so that both are collected in the same GC pass,
their finalizer may be invoked in any order.
If the Socket gets finalized first, it's
SafeSocketHandlewill have a_mstateof 8 (two references) at the beginning of
DangerousReleaseInternal()- whichwill set it to 6 (one reference plus disposed flag).
Then when the
SafePipeHandlegets collected, it will callDangerousRelease ()on it's
SafeSocketHandle. As mentioned above, it's_mstatewill be 6.Now we own the handle, so we'll decrease it's reference count by one and set the
Closedflag - the new_mstateshould thus be 3.However, using
would set it to 1 - thus effectively clearing the `Disposed' flag. And since it's
reference count is now also zero, the next finalize pass will then throw.
The CoreCLR version of this class uses
which fixes this.
Backport of #16244.
/cc @steveisok @baulig