From 7915e452428ec79f53ec4bb1e7ebdc81807569c2 Mon Sep 17 00:00:00 2001 From: Juliette Cordor Date: Fri, 8 Sep 2023 23:15:21 +1000 Subject: [PATCH 1/3] refactored cominit usage --- src/win/mod.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/win/mod.rs b/src/win/mod.rs index d7fb766..7fe1dc1 100644 --- a/src/win/mod.rs +++ b/src/win/mod.rs @@ -16,23 +16,24 @@ pub(crate) struct ComInit { initialized: bool, } -impl ComInit { - pub(crate) fn init() { - let is_init = unsafe { Self::init_com() }.is_ok(); - COM_INIT.lock().unwrap().initialized = is_init; - } +#[derive(Debug, thiserror::Error)] +pub(crate) enum ComError { + #[error("Failed to lock COM_INIT variable: {0}")] + LockError(#[from] std::sync::PoisonError>), +} - unsafe fn init_com() -> Result<(), windows::core::Error> { - let mut com_init = COM_INIT.lock().unwrap(); +impl ComInit { + pub(crate) unsafe fn init() -> Result<(), ComError> { + let mut com_init = COM_INIT.lock()?; if !com_init.initialized { - CoInitializeEx(None, COINIT_MULTITHREADED)?; - com_init.initialized = true; + com_init.initialized = CoInitializeEx(None, COINIT_MULTITHREADED).is_ok(); } Ok(()) } } +// As COM_INIT is a static variable this will be dropped at the end of the program. impl Drop for ComInit { fn drop(&mut self) { unsafe { CoUninitialize() } From b9faf8bbd5b8f235e8e35d692e45bd032877ce87 Mon Sep 17 00:00:00 2001 From: Juliette Cordor Date: Fri, 8 Sep 2023 23:20:46 +1000 Subject: [PATCH 2/3] expect unpoisoned mutex Realistically, the lock method only returns an error if another thread panicked while holding the mutex. This could only happen if te init function panicked, which would only happen if there was a bug in the windows-rs crate, in which case there are greater issues than this specific function panicking. --- src/win/mod.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/win/mod.rs b/src/win/mod.rs index 7fe1dc1..f49f6e5 100644 --- a/src/win/mod.rs +++ b/src/win/mod.rs @@ -23,13 +23,11 @@ pub(crate) enum ComError { } impl ComInit { - pub(crate) unsafe fn init() -> Result<(), ComError> { - let mut com_init = COM_INIT.lock()?; + pub(crate) unsafe fn init() { + let mut com_init = COM_INIT.lock().expect("unpoisoned mutex"); if !com_init.initialized { com_init.initialized = CoInitializeEx(None, COINIT_MULTITHREADED).is_ok(); } - - Ok(()) } } From cf0deca29f27540f2bec96a4ad9ed5a68aa3bacc Mon Sep 17 00:00:00 2001 From: Juliette Cordor Date: Fri, 8 Sep 2023 23:21:03 +1000 Subject: [PATCH 3/3] move COM_INIT static var lower --- src/win/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win/mod.rs b/src/win/mod.rs index f49f6e5..2b71266 100644 --- a/src/win/mod.rs +++ b/src/win/mod.rs @@ -4,13 +4,13 @@ use std::sync::Mutex; use windows::Win32::System::Com::{CoInitializeEx, CoUninitialize, COINIT_MULTITHREADED}; -pub(crate) static COM_INIT: Mutex = Mutex::new(ComInit { initialized: false }); - #[cfg(feature = "network")] pub mod network; #[cfg(feature = "root")] pub mod root; +pub(crate) static COM_INIT: Mutex = Mutex::new(ComInit { initialized: false }); + #[derive(Debug, Clone)] pub(crate) struct ComInit { initialized: bool,