diff --git a/Cargo.toml b/Cargo.toml index 3cbb54b5..d4bdf654 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = ["hdf5", "hdf5-types", "hdf5-derive", "hdf5-sys", "hdf5-src"] default-members = ["hdf5", "hdf5-types", "hdf5-derive", "hdf5-sys"] [workspace.package] -version = "0.9.0" # !V +version = "0.9.1" # !V rust-version = "1.77.0" authors = [ "Ivan Smirnov ", @@ -29,5 +29,5 @@ regex = "1.10" hdf5 = { package = "hdf5-metno", version = "0.9.0", path = "hdf5" } # !V hdf5-derive = { package = "hdf5-metno-derive", version = "0.9.0", path = "hdf5-derive" } # !V hdf5-src = { package = "hdf5-metno-src", version = "0.9.0", path = "hdf5-src" } # !V -hdf5-sys = { package = "hdf5-metno-sys", version = "0.9.0", path = "hdf5-sys" } # !V +hdf5-sys = { package = "hdf5-metno-sys", version = "0.9.1", path = "hdf5-sys" } # !V hdf5-types = { package = "hdf5-metno-types", version = "0.9.0", path = "hdf5-types" } # !V diff --git a/hdf5-sys/Cargo.toml b/hdf5-sys/Cargo.toml index e74e048f..ae09b6f9 100644 --- a/hdf5-sys/Cargo.toml +++ b/hdf5-sys/Cargo.toml @@ -19,6 +19,7 @@ libc = { workspace = true } mpi-sys = { workspace = true, optional = true } libz-sys = { workspace = true, optional = true } hdf5-src = { workspace = true, optional = true } +parking_lot = "0.12.3" # Please see README for further explanation of these feature flags [features] diff --git a/hdf5-sys/src/lib.rs b/hdf5-sys/src/lib.rs index 0a736fa0..f29df8cd 100644 --- a/hdf5-sys/src/lib.rs +++ b/hdf5-sys/src/lib.rs @@ -65,6 +65,10 @@ mod internal_prelude { }; } +use parking_lot::ReentrantMutex; +/// Lock which can be used to serialise access to the hdf5 library +pub static LOCK: ReentrantMutex<()> = ReentrantMutex::new(()); + #[cfg(test)] mod tests { use super::h5::H5open; diff --git a/hdf5/Cargo.toml b/hdf5/Cargo.toml index edf746e1..b6f0dbec 100644 --- a/hdf5/Cargo.toml +++ b/hdf5/Cargo.toml @@ -46,7 +46,6 @@ libc = { workspace = true } lzf-sys = { version = "0.1", optional = true } mpi-sys = { workspace = true, optional = true } ndarray = "0.15" -parking_lot = "0.12" paste = "1.0" # internal hdf5-derive = { workspace = true } @@ -56,6 +55,7 @@ hdf5-types = { workspace = true } [dev-dependencies] half = { workspace = true } num-complex = { workspace = true } +parking_lot = "0.12.3" paste = "1.0" pretty_assertions = "1.4" rand = { version = "0.8", features = ["small_rng"] } diff --git a/hdf5/src/globals.rs b/hdf5/src/globals.rs index e1b9461f..16f17421 100644 --- a/hdf5/src/globals.rs +++ b/hdf5/src/globals.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] use std::mem; +use std::sync::LazyLock; use lazy_static::lazy_static; @@ -24,7 +25,7 @@ pub struct H5GlobalConstant( impl std::ops::Deref for H5GlobalConstant { type Target = hdf5_sys::h5i::hid_t; fn deref(&self) -> &Self::Target { - lazy_static::initialize(&crate::sync::LIBRARY_INIT); + LazyLock::force(&crate::sync::LIBRARY_INIT); cfg_if::cfg_if! { if #[cfg(msvc_dll_indirection)] { let dll_ptr = self.0 as *const usize; diff --git a/hdf5/src/sync.rs b/hdf5/src/sync.rs index 80b6eb44..7783325d 100644 --- a/hdf5/src/sync.rs +++ b/hdf5/src/sync.rs @@ -1,40 +1,32 @@ use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::LazyLock; -use lazy_static::lazy_static; -use parking_lot::ReentrantMutex; +pub(crate) use hdf5_sys::LOCK; thread_local! { pub static SILENCED: AtomicBool = AtomicBool::new(false); } -lazy_static! { - pub(crate) static ref LIBRARY_INIT: () = { - // No functions called here must try to create the LOCK, - // as this could cause a deadlock in initialisation - unsafe { - // Ensure hdf5 does not invalidate handles which might - // still be live on other threads on program exit - ::hdf5_sys::h5::H5dont_atexit(); - ::hdf5_sys::h5::H5open(); - // Ignore errors on stdout - crate::error::silence_errors_no_sync(true); - // Register filters lzf/blosc if available - crate::hl::filters::register_filters(); - } - }; -} +pub(crate) static LIBRARY_INIT: LazyLock<()> = LazyLock::new(|| { + let _guard = hdf5_sys::LOCK.lock(); + unsafe { + // Ensure hdf5 does not invalidate handles which might + // still be live on other threads on program exit + ::hdf5_sys::h5::H5dont_atexit(); + ::hdf5_sys::h5::H5open(); + // Ignore errors on stdout + crate::error::silence_errors_no_sync(true); + // Register filters lzf/blosc if available + crate::hl::filters::register_filters(); + } +}); /// Guards the execution of the provided closure with a recursive static mutex. pub fn sync(func: F) -> T where F: FnOnce() -> T, { - lazy_static! { - static ref LOCK: ReentrantMutex<()> = { - lazy_static::initialize(&LIBRARY_INIT); - ReentrantMutex::new(()) - }; - } + let _ = LazyLock::force(&LIBRARY_INIT); SILENCED.with(|silence| { let is_silenced = silence.load(Ordering::Acquire); if !is_silenced {