2015-09-01 09:23:41 +00:00
|
|
|
//! Handles COM initialization and cleanup.
|
|
|
|
|
|
|
|
use super::check_result;
|
2017-10-11 11:24:49 +00:00
|
|
|
use std::ptr;
|
2015-09-01 09:23:41 +00:00
|
|
|
|
2018-02-07 16:36:59 +00:00
|
|
|
use super::winapi::um::objbase::{COINIT_MULTITHREADED};
|
|
|
|
use super::winapi::um::combaseapi::{CoInitializeEx, CoUninitialize};
|
|
|
|
|
2015-09-01 09:23:41 +00:00
|
|
|
thread_local!(static COM_INITIALIZED: ComInitialized = {
|
|
|
|
unsafe {
|
|
|
|
// this call can fail if another library initialized COM in single-threaded mode
|
|
|
|
// handling this situation properly would make the API more annoying, so we just don't care
|
2018-02-07 16:36:59 +00:00
|
|
|
check_result(CoInitializeEx(ptr::null_mut(), COINIT_MULTITHREADED)).unwrap();
|
2015-09-01 09:23:41 +00:00
|
|
|
ComInitialized(ptr::null_mut())
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/// RAII object that guards the fact that COM is initialized.
|
|
|
|
///
|
|
|
|
// We store a raw pointer because it's the only way at the moment to remove `Send`/`Sync` from the
|
|
|
|
// object.
|
|
|
|
struct ComInitialized(*mut ());
|
|
|
|
|
|
|
|
impl Drop for ComInitialized {
|
2015-09-11 08:55:29 +00:00
|
|
|
#[inline]
|
2015-09-01 09:23:41 +00:00
|
|
|
fn drop(&mut self) {
|
2018-02-07 16:36:59 +00:00
|
|
|
unsafe { CoUninitialize() };
|
2015-09-01 09:23:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Ensures that COM is initialized in this thread.
|
2015-09-11 08:55:29 +00:00
|
|
|
#[inline]
|
2015-09-01 09:23:41 +00:00
|
|
|
pub fn com_initialized() {
|
|
|
|
COM_INITIALIZED.with(|_| {});
|
|
|
|
}
|