Skip to content

[Win32] Initialize Windows Runtime on queue threads #595

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

Merged
merged 1 commit into from
Sep 13, 2023

Conversation

triplef
Copy link
Contributor

@triplef triplef commented Feb 22, 2022

On Windows, all threads that want to use Windows Runtime or COM components must be initialized with a call to CoInitializeEx() or the slightly more modern RoInitialize() (same as Windows::Foundation::Initialize).

This change initializes all libdispatch threads so it’s possible to use COM and Windows Runtime APIs.

@rokhinip rokhinip requested a review from compnerd February 22, 2022 20:05
@stevenbrix
Copy link

is it possible to have app authors determine which initialization method to use? would this make the @MainActor thread an MTA thread? that should likely be STA (which is what conventional Windows GUI apps use today)

@compnerd
Copy link
Member

is it possible to have app authors determine which initialization method to use? would this make the @MainActor thread an MTA thread? that should likely be STA (which is what conventional Windows GUI apps use today)

No, I don't see how to do that. These threads are spawned without user intervention, and I don't remember any APIs to control the worker threads it creates. Is there a global Windows API that lets you set the apartment model?

@stevenbrix
Copy link

@compnerd given the behavior of .NET it seems correct to initialize background threads to MTA: https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.setapartmentstate?view=net-7.0#remarks

if needed perhaps we could evolve this in the future but not an immediate need

@compnerd
Copy link
Member

@compnerd given the behavior of .NET it seems correct to initialize background threads to MTA: https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.setapartmentstate?view=net-7.0#remarks

if needed perhaps we could evolve this in the future but not an immediate need

Well, this is only for background threads, so this sounds like we have a path forward. I think that the only thing missing here is the death for an error scenario.

@triplef any chance you can update the patch?

Copy link

@stevenbrix stevenbrix left a comment

Choose a reason for hiding this comment

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

@compnerd
Copy link
Member

looks like ignoring an unexpected HRESULT might be acceptable?

It may be that its easier to debug the .NET runtime, things are a bit more complicated with debugging dispatch, I'd rather be more stringent. The number of times that the dispatch assertions have saved me hours of debugging is ridiculous. Blindly following .NET doesn't seem like the right thing to me.

@triplef
Copy link
Contributor Author

triplef commented Sep 10, 2023

I’ve updated the patch with a fatal error message in case COM initialization fails. Let me know if there’s any other changes needed.

@compnerd
Copy link
Member

@swift-ci please test

@compnerd
Copy link
Member

@swift-ci please test Windows platform

1 similar comment
@compnerd
Copy link
Member

@swift-ci please test Windows platform

@compnerd compnerd merged commit 2f76085 into swiftlang:main Sep 13, 2023
@triplef triplef deleted the win-thread-mta branch September 13, 2023 05:07
return 0;
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) {
_dispatch_client_assert_fail("Error %ld initializing Windows Runtime", hr);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we safely assume that CoInitializeEx is enough to initialize the Windows Runtime, when Roinitialize doesn't mention this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There was an earlier discussion about these functions here, does that maybe answer your question? Unfortunately I’m not familiar with the differences between the two functions.

Copy link

Choose a reason for hiding this comment

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

CoInitializeEx initialize concurrent model as STA, where RoInitialize by default uses MTA. Though passing RO_INIT_SINGLETHREADED will use STA instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants