Skip to content

Conversation

@vmoroz
Copy link
Member

@vmoroz vmoroz commented Apr 30, 2020

If user code directly inherits from the XAML Application class then it works just fine.
The issue is that if we inherit our ReactApplication from the XAML Applicaiton, and then user code inherits from the ReacApplication, then the C++/WinRT current COM aggregation fails to work correctly and we have a crash.

To work around the crash we have added the following lines to the user App constructor:

App::App() noexcept {
 ....
 // This works around a cpp/winrt bug with composable/aggregable types tracked
 // by 22116519
 AddRef();
 m_inner.as<::IUnknown>()->Release();
}

It was good for a quick workaround while we worked on the ReactApplication prototype, but in the long run this code has no place in user applications, especially the Windows bug number that has no meaning for non-Microsoft users.

In this PR we are implementing a work around inside of our ReactApplication suggested by @jevansaks. The change makes sure that we pass a correct pointer to the outer class for the COM aggregation to work. It allowed us to remove the work around bits from the sample and template code.

IMPORTANT: All previously created applications MUST remove the work around code mentioned above to work with the new Microsoft.ReactNative.dll. Otherwise, they will crash. The new solution frees the user code from the work-around, but this is also a requirement to have applications working.

Microsoft Reviewers: Open in CodeFlow

@vmoroz vmoroz added the Breaking Change This PR will break existing apps and should be part of the known breaking changes for the release label Apr 30, 2020
@vmoroz vmoroz requested a review from a team as a code owner April 30, 2020 15:53
@vmoroz vmoroz changed the title Removed the ref count work around from classes derived from ReactApplications Removed AddRef/Release from classes derived from ReactApplications Apr 30, 2020
@vmoroz vmoroz changed the title Removed AddRef/Release from classes derived from ReactApplications Removed the ref count work around from classes derived from ReactApplication Apr 30, 2020
using base_type = NoDefaultCtorReactApplication_base;
using class_type = Microsoft::ReactNative::ReactApplication;
using implements_type = typename NoDefaultCtorReactApplication_base::implements_type;
using implements_type::implements_type;
Copy link

Choose a reason for hiding this comment

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

using implements_type::implements_type; [](start = 2, length = 39)

(nit) what does this do?

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 brings constructors from the implements_type base class. I am not sure why it is need. I effectively copy&pasted the generated code and did minimal changes to it: deleted default constructor.


In reply to: 418146298 [](ancestors = 418146298)

Copy link

@NikoAri NikoAri left a comment

Choose a reason for hiding this comment

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

:shipit:

@jevansaks
Copy link
Member

IMPORTANT: All previously created applications MUST remove the work around code mentioned above to work with the new Microsoft.ReactNative.dll. Otherwise, they will crash

It occurred to me that we might be able to cause user code using this pattern to fail to compile instead by exposing an "m_inner" protected field on ReactApplication of a bogus type. Then code of the old pattern would fail to compile with something like "no member Release()" or "ambiguous blah blah".

}
};

struct ReactApplication : NoDefaultCtorReactApplication_base<ReactApplication> {
Copy link
Member

Choose a reason for hiding this comment

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

Why did the base type for this need to change? Was there something provided in the generated code that was conflicting with this override?

Copy link
Member Author

Choose a reason for hiding this comment

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

The default constructor of the ReactApplicationT calls the factory for the XAML Application class. If I do not replace the base class, then the XAML Application is going to be created twice: one in the base default constructor and the second in the our constructor with the outer reference.

Ideally, the generated class must have two constructors or one with an optional outer parameter.


In reply to: 418151912 [](ancestors = 418151912)

Copy link
Member

Choose a reason for hiding this comment

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

Oh I see. Yes that makes sense.

@vmoroz
Copy link
Member Author

vmoroz commented Apr 30, 2020

I do not see how we can do it. Users consume this code through the ABI boundary. There is nothing we can add there to make it fail. The code here does not affect the C++/WinRT generated code that is consumed in the user code.


In reply to: 621973435 [](ancestors = 621973435)

@jevansaks
Copy link
Member

I do not see how we can do it. Users consume this code through the ABI boundary. There is nothing we can add there to make it fail. The code here does not affect the C++/WinRT generated code that is consumed in the user code.

Oh right, the m_inner is the one from C++/WinRT in the app's code. Hmmm. Well if this becomes a problem and we want a more visible way to flag it we might be able to come up with a way to detect this in ReactApplication at runtime.

@NickGerleman
Copy link
Contributor

NickGerleman commented Apr 30, 2020

@vmoroz what's the motivation for getting this one into 0.62 instead of waiting until 0.63 (which should be coming sooner rather than later)?

Breaking changes in stable branches are best to avoid if possible. API defects in new bits are a good reason to cause breaks, but this issue has been around since 0.60 or 0.61, right?

@vmoroz vmoroz removed Backport to 0.62 Breaking Change This PR will break existing apps and should be part of the known breaking changes for the release labels Apr 30, 2020
@vmoroz
Copy link
Member Author

vmoroz commented Apr 30, 2020

I thought it would be better overall, since the 0.62 is not completely stable yet and it is the version people will try after the Build conference. Since it is a breaking change, we will have more unhappy customers down the road. Porting this to 0.62 seems to be a 'less evil' than doing it in a month. Anyway, I do not have a strong opinion about it. I am OK making it 0.63 only and thus removed the both tags.


In reply to: 622026743 [](ancestors = 622026743)

@vmoroz
Copy link
Member Author

vmoroz commented Apr 30, 2020

Agree. We should see first if it becomes a big problem after the release.


In reply to: 622009181 [](ancestors = 622009181)

@vmoroz vmoroz merged commit 9d9a541 into microsoft:master Apr 30, 2020
@NickGerleman NickGerleman added the Breaking Change This PR will break existing apps and should be part of the known breaking changes for the release label May 1, 2020
@NickGerleman
Copy link
Contributor

Adding the "breaking change" label back since we will want to document this regardless of when it goes in.

I can totally sympathize with wanting this in sooner so less people end up using the API in the first place. I'd still probably rather hold off on 0.62 just because we're trying to explicitly avoid breaking changes in preview builds when they aren't to correct issues we've just introduced.

NickGerleman pushed a commit to NickGerleman/react-native-windows that referenced this pull request May 6, 2020
…ication (microsoft#4755)

* Removed the ref count work around from classes derived from ReactApplications

* Change files
NickGerleman pushed a commit to NickGerleman/react-native-windows that referenced this pull request May 7, 2020
…ication (microsoft#4755)

* Removed the ref count work around from classes derived from ReactApplications

* Change files
NickGerleman added a commit to NickGerleman/react-native-windows that referenced this pull request May 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Breaking Change This PR will break existing apps and should be part of the known breaking changes for the release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants