-
Notifications
You must be signed in to change notification settings - Fork 410
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
change from COINIT_MULTITHREADED to COINIT_APARTMENTTHREADED in wasapi #504
Conversation
See #348; I still have the same stance and I'm skeptical to the changes, as the Windows documentation on threading is very confusing and no one had the expertise to prove that changing the thread model would be safe under our |
Just read through #348 again. Can you suggest any small actionable steps that can be taken in order to progress this then? |
I don't know if you use drag and drop, but if you don't, then winit has already merged a PR allowing cpal to winit to co-exist if you initialize winit first: rust-windowing/winit#1524 Otherwise, I'm sorry but I don't think the situation would change unless someone can "prove" apartment threading is safe. Well, I don't know, if there's constant complaints that this need to change, then I might try the less safe way and see if it breaks in public use cases, but since winit has the compatibility code for now, I doubt that it's worth introducing some potential unsafety. |
According to this link CoInitialzeEx has to be called once per thread, so I think it is up to the application to make sure that it doesn't use incompatible COM libraries in the same thread. Winit obviously has to live in the main (GUI) thread, but cpal (WasApi) should be able to initialized in another thread than the main thread and use COINIT_MULTITHREADED so that after that cpal calls can be called from whatever thread you like. |
COM can prevent undefined behavior in either concurrency model by performing marshaling when necessary. As a result, CoInitializeEx can be called with either concurrency model, and in this case STA provides better compatibility with other code requiring STA, e.g. ASIO backend or winit drag-and-drop. To dive into the detail, the entry point of WASAPI, MMDeviceEnumerator, is registered with "both" threading model, which means that COM objects are created with whatever the thread's concurrency model is set to. This raises the concern that when STA is used, marshaling might make audio buffer operations block on the main thread, breaking continuous audio processing. However, the implementation actually uses free-threaded marshaller for interfaces dealing with buffer operations, which effectively bypasses COM's compatibility marshaling behavior and perform any API calls on the caller's thread instead. Therefore, the interfaces would operate just fine on either concurrency model. For more details on COM's threading model, see [1]. [1] https://thrysoee.dk/InsideCOM+/ch04d.htm Co-Authored-By: Henrik Rydgård <hrydgard@gmail.com> Close RustAudio#348 Close RustAudio#504 Close RustAudio#538
COM can prevent undefined behavior in either concurrency model by performing marshaling when necessary. As a result, CoInitializeEx can be called with either concurrency model, and in this case STA provides better compatibility with other code requiring STA, e.g. ASIO backend or winit drag-and-drop. To dive into the detail, the entry point of WASAPI, MMDeviceEnumerator, is registered with "both" threading model, which means that COM objects are created with whatever the thread's concurrency model is set to. This raises the concern that when STA is used, marshaling might make audio buffer operations block on the main thread, breaking continuous audio processing. However, the implementation actually uses free-threaded marshaller for interfaces dealing with buffer operations, which effectively bypasses COM's compatibility marshaling behavior and perform any API calls on the caller's thread instead. Therefore, the interfaces would operate just fine on either concurrency model. For more details on COM's threading model, see [1]. [1] https://thrysoee.dk/InsideCOM+/ch04d.htm Co-Authored-By: Henrik Rydgård <hrydgard@gmail.com> Close RustAudio#348 Close RustAudio#504 Close RustAudio#538
COM can prevent undefined behavior in either concurrency model by performing marshaling when necessary. As a result, CoInitializeEx can be called with either concurrency model, and in this case STA provides better compatibility with other code requiring STA, e.g. ASIO backend or winit drag-and-drop. To dive into the detail, the entry point of WASAPI, MMDeviceEnumerator, is registered with "both" threading model, which means that COM objects are created with whatever the thread's concurrency model is set to. This raises the concern that when STA is used, marshaling might make audio buffer operations block on the main thread, breaking continuous audio processing. However, the implementation actually uses free-threaded marshaller for interfaces dealing with buffer operations, which effectively bypasses COM's compatibility marshaling behavior and perform any API calls on the caller's thread instead. Therefore, the interfaces would operate just fine on either concurrency model. For more details on COM's threading model, see [1]. [1] https://thrysoee.dk/InsideCOM+/ch04d.htm Co-Authored-By: Henrik Rydgård <hrydgard@gmail.com> Close RustAudio#348 Close RustAudio#504 Close RustAudio#538
COM can prevent undefined behavior in either concurrency model by performing marshaling when necessary. As a result, CoInitializeEx can be called with either concurrency model, and in this case STA provides better compatibility with other code requiring STA, e.g. ASIO backend or winit drag-and-drop. To dive into the detail, the entry point of WASAPI, MMDeviceEnumerator, is registered with "both" threading model, which means that COM objects are created with whatever the thread's concurrency model is set to. This raises the concern that when STA is used, marshaling might make audio buffer operations block on the main thread, breaking continuous audio processing. However, the implementation actually uses free-threaded marshaller for interfaces dealing with buffer operations, which effectively bypasses COM's compatibility marshaling behavior and perform any API calls on the caller's thread instead. Therefore, the interfaces would operate just fine on either concurrency model. For more details on COM's threading model, see [1]. [1] https://thrysoee.dk/InsideCOM+/ch04d.htm Co-Authored-By: Henrik Rydgård <hrydgard@gmail.com> Close RustAudio#59 Close RustAudio#348 Close RustAudio#504 Close RustAudio#530 Close RustAudio#538 Close RustAudio#572
There is currently a problem in windows when trying to use cpal with winit 0.20.
Winit now uses
COINIT_APARTMENTTHREADED
because it is required by the OLE API they are using to properly handle file dropping. See this link for more information@bolcom ran into this problem and submitted PR #330 to address this but it was never merged, and instead decided to spin up a whole separate thread for using winit. I also noted that @ishitatsuyuki was concerned that moving to apartment threading would require marshaling. I don't really understand what this means, would be nice to hear further clarification as to what this would actually involve.
It would be nice if cpal and winit could share the same threading model so users on windows didn't have to spin up separate threads. Keen to hear poeples thoughts.