nandi/jolt-nativepublic Fork 0
fa4ecdfed6a830e6099d5fab9be24ef72ea1923b
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

com.rs · 56 lines · 1.9 KBRust Blame HistoryRaw
Lift freeq's AV media plane out of sleek 90f8b89 nandi 19d ago1//! Handles COM initialization and cleanup.
2
3use std::io::Error as IoError;
4use std::marker::PhantomData;
5
6use windows::Win32::Foundation::RPC_E_CHANGED_MODE;
7use windows::Win32::System::Com::{CoInitializeEx, CoUninitialize, COINIT_APARTMENTTHREADED};
8
9thread_local!(static COM_INITIALIZED: ComInitialized = {
10 unsafe {
11 // Try to initialize COM with STA by default to avoid compatibility issues with the ASIO
12 // backend (where CoInitialize() is called by the ASIO SDK) or winit (where drag and drop
13 // requires STA).
14 // This call can fail with RPC_E_CHANGED_MODE if another library initialized COM with MTA.
15 // That's OK though since COM ensures thread-safety/compatibility through marshalling when
16 // necessary.
17 let result = CoInitializeEx(None, COINIT_APARTMENTTHREADED);
18 if result.is_ok() || result == RPC_E_CHANGED_MODE {
19 ComInitialized {
20 result,
21 _ptr: PhantomData,
22 }
23 } else {
24 // COM initialization failed in another way, something is really wrong.
25 panic!(
26 "Failed to initialize COM: {}",
27 IoError::from_raw_os_error(result.0)
28 );
29 }
30 }
31});
32
33/// RAII object that guards the fact that COM is initialized.
34///
35// We store a raw pointer because it's the only way at the moment to remove `Send`/`Sync` from the
36// object.
37struct ComInitialized {
38 result: windows::core::HRESULT,
39 _ptr: PhantomData<*mut ()>,
40}
41
42impl Drop for ComInitialized {
43 fn drop(&mut self) {
44 // Need to avoid calling CoUninitialize() if CoInitializeEx failed since it may have
45 // returned RPC_E_MODE_CHANGED - which is OK, see above.
46 if self.result.is_ok() {
47 unsafe { CoUninitialize() };
48 }
49 }
50}
51
52/// Ensures that COM is initialized in this thread.
53#[inline]
54pub fn com_initialized() {
55 COM_INITIALIZED.with(|_| {});
56}