wasmtime/
sync_std.rs

1//! Synchronization primitives for Wasmtime.
2//!
3//! This is a small set of primitives split between std and no_std with "dummy"
4//! implementation on no_std. The no_std implementations live in
5//! `sync_nostd.rs`.
6
7use once_cell::sync::OnceCell;
8use std::ops::{Deref, DerefMut};
9
10/// This type is intended to mirror, and one day be implemented by, the
11/// `std::sync::OnceLock` type. At this time
12/// `std::sync::OnceLock::get_or_try_init` is not stable so for now this is
13/// implemented with the `once_cell` crate instead.
14pub struct OnceLock<T>(OnceCell<T>);
15
16impl<T> OnceLock<T> {
17    #[inline]
18    pub const fn new() -> OnceLock<T> {
19        OnceLock(OnceCell::new())
20    }
21
22    #[inline]
23    pub fn get_or_init(&self, f: impl FnOnce() -> T) -> &T {
24        self.0.get_or_init(f)
25    }
26
27    #[inline]
28    pub fn get_or_try_init<E>(&self, f: impl FnOnce() -> Result<T, E>) -> Result<&T, E> {
29        self.0.get_or_try_init(f)
30    }
31}
32
33impl<T> Default for OnceLock<T> {
34    fn default() -> OnceLock<T> {
35        OnceLock::new()
36    }
37}
38
39/// Small wrapper around `std::sync::RwLock` which undoes poisoning.
40#[derive(Debug, Default)]
41pub struct RwLock<T>(std::sync::RwLock<T>);
42
43impl<T> RwLock<T> {
44    #[inline]
45    pub const fn new(val: T) -> RwLock<T> {
46        RwLock(std::sync::RwLock::new(val))
47    }
48
49    #[inline]
50    pub fn read(&self) -> impl Deref<Target = T> + '_ {
51        self.0.read().unwrap()
52    }
53
54    #[inline]
55    pub fn write(&self) -> impl DerefMut<Target = T> + '_ {
56        self.0.write().unwrap()
57    }
58}