Skip to content

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 area-NativeAOT-coreclr community-contribution Indicates that the PR has been added by a community member labels 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 <jkoritzinsky@gmail.com>
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