Skip to content
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

NativeAOT ComWrappers: extend managed object lifetime based on refcount #85087

Merged
merged 6 commits into from
Apr 21, 2023

Conversation

AustinWise
Copy link
Contributor

This PR builds on #84927 by @kant2002 and is inspired by the comment by @jkoritzinsky. It uses a ref-counted GC handle to extend the lifetime of the managed object while the managed object wrapper still has a non-zero refcount.

I have added two test cases to the ComWrappers unit tests to show the problem. On the main branch the tests pass on CoreCLR and fail on NativeAOT. The tests pass on NativeAOT after this change.

kant2002 and others added 2 commits April 19, 2023 20:54
Fixes: microsoft/CsWinRT#1321
Make ComWrappers in C# work closely with how C++ part works
- `RefCount` => `curr` is plain typo
- Do not destroy wrappers if ref count == 0. That's mimic how CoreCLR work
- Also discover 2 tests which are plainly wrong, since they do not work under CoreCLR
@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Apr 20, 2023
@ghost
Copy link

ghost commented Apr 20, 2023

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

Issue Details

This PR builds on #84927 by @kant2002 and is inspired by the comment by @jkoritzinsky. It uses a ref-counted GC handle to extend the lifetime of the managed object while the managed object wrapper still has a non-zero refcount.

I have added two test cases to the ComWrappers unit tests to show the problem. On the main branch the tests pass on CoreCLR and fail on NativeAOT. The tests pass on NativeAOT after this change.

Author: AustinWise
Assignees: -
Labels:

community-contribution, area-NativeAOT-coreclr

Milestone: -

These now pass again with the ref counted handle.
{
get
{
IntPtr handle = HolderHandle;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other accesses to HolderHandle seem to be using interlocked APIs (which mean they also imply having volatile semantics for reads/writes). Should this read be volatile (or, just the field itself be marked as such) for consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add an Interlocked.Read here.

The existing RefCount field has potentially the same problem. It is updated using interlocked but read using simple field access in some places. I am not familiar enough with the memory model of .NET to know if this is "ok".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, Interlocked.Read only exists for Int64 and UInt64. I'll use volatile.

…e/InteropServices/ComWrappers.NativeAot.cs

Co-authored-by: Jeremy Koritzinsky <[email protected]>
Copy link
Member

@jkoritzinsky jkoritzinsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've validated that this works locally

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-NativeAOT-coreclr community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants