181a89169SAlex Crichton //! Synchronization primitives for Wasmtime. 281a89169SAlex Crichton //! 381a89169SAlex Crichton //! This is a small set of primitives split between std and no_std with "dummy" 481a89169SAlex Crichton //! implementation on no_std. The no_std implementations live in 581a89169SAlex Crichton //! `sync_nostd.rs`. 681a89169SAlex Crichton 781a89169SAlex Crichton use once_cell::sync::OnceCell; 881a89169SAlex Crichton use std::ops::{Deref, DerefMut}; 981a89169SAlex Crichton 1081a89169SAlex Crichton /// This type is intended to mirror, and one day be implemented by, the 1181a89169SAlex Crichton /// `std::sync::OnceLock` type. At this time 1281a89169SAlex Crichton /// `std::sync::OnceLock::get_or_try_init` is not stable so for now this is 1381a89169SAlex Crichton /// implemented with the `once_cell` crate instead. 1481a89169SAlex Crichton pub struct OnceLock<T>(OnceCell<T>); 1581a89169SAlex Crichton 1681a89169SAlex Crichton impl<T> OnceLock<T> { 1781a89169SAlex Crichton #[inline] new() -> OnceLock<T>1881a89169SAlex Crichton pub const fn new() -> OnceLock<T> { 1981a89169SAlex Crichton OnceLock(OnceCell::new()) 2081a89169SAlex Crichton } 2181a89169SAlex Crichton 2281a89169SAlex Crichton #[inline] get_or_init(&self, f: impl FnOnce() -> T) -> &T2381a89169SAlex Crichton pub fn get_or_init(&self, f: impl FnOnce() -> T) -> &T { 2481a89169SAlex Crichton self.0.get_or_init(f) 2581a89169SAlex Crichton } 2681a89169SAlex Crichton 2781a89169SAlex Crichton #[inline] get_or_try_init<E>(&self, f: impl FnOnce() -> Result<T, E>) -> Result<&T, E>2881a89169SAlex Crichton pub fn get_or_try_init<E>(&self, f: impl FnOnce() -> Result<T, E>) -> Result<&T, E> { 2981a89169SAlex Crichton self.0.get_or_try_init(f) 3081a89169SAlex Crichton } 3181a89169SAlex Crichton } 3281a89169SAlex Crichton 33*e60b6e62SAlex Crichton impl<T> Default for OnceLock<T> { default() -> OnceLock<T>34*e60b6e62SAlex Crichton fn default() -> OnceLock<T> { 35*e60b6e62SAlex Crichton OnceLock::new() 36*e60b6e62SAlex Crichton } 37*e60b6e62SAlex Crichton } 38*e60b6e62SAlex Crichton 3981a89169SAlex Crichton /// Small wrapper around `std::sync::RwLock` which undoes poisoning. 4081a89169SAlex Crichton #[derive(Debug, Default)] 4181a89169SAlex Crichton pub struct RwLock<T>(std::sync::RwLock<T>); 4281a89169SAlex Crichton 4381a89169SAlex Crichton impl<T> RwLock<T> { 4481a89169SAlex Crichton #[inline] new(val: T) -> RwLock<T>4581a89169SAlex Crichton pub const fn new(val: T) -> RwLock<T> { 4681a89169SAlex Crichton RwLock(std::sync::RwLock::new(val)) 4781a89169SAlex Crichton } 4881a89169SAlex Crichton 4981a89169SAlex Crichton #[inline] read(&self) -> impl Deref<Target = T> + '_5081a89169SAlex Crichton pub fn read(&self) -> impl Deref<Target = T> + '_ { 5181a89169SAlex Crichton self.0.read().unwrap() 5281a89169SAlex Crichton } 5381a89169SAlex Crichton 5481a89169SAlex Crichton #[inline] write(&self) -> impl DerefMut<Target = T> + '_5581a89169SAlex Crichton pub fn write(&self) -> impl DerefMut<Target = T> + '_ { 5681a89169SAlex Crichton self.0.write().unwrap() 5781a89169SAlex Crichton } 5881a89169SAlex Crichton } 59