naga/
racy_lock.rs

1#![cfg_attr(
2    not(any(glsl_out, hlsl_out, msl_out, feature = "wgsl-in", wgsl_out)),
3    expect(
4        dead_code,
5        reason = "RacyLock is only required for the above configurations"
6    )
7)]
8
9use alloc::boxed::Box;
10use once_cell::race::OnceBox;
11
12/// An alternative to [`LazyLock`] based on [`OnceBox`].
13///
14/// [`LazyLock`]: https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html
15pub struct RacyLock<T: 'static> {
16    inner: OnceBox<T>,
17    init: fn() -> T,
18}
19
20impl<T: 'static> RacyLock<T> {
21    /// Creates a new [`RacyLock`], which will initialize using the provided `init` function.
22    pub const fn new(init: fn() -> T) -> Self {
23        Self {
24            inner: OnceBox::new(),
25            init,
26        }
27    }
28
29    /// Loads the internal value, initializing it if required.
30    pub fn get(&self) -> &T {
31        self.inner.get_or_init(|| Box::new((self.init)()))
32    }
33}
34
35impl<T: 'static> core::ops::Deref for RacyLock<T> {
36    type Target = T;
37
38    fn deref(&self) -> &Self::Target {
39        self.get()
40    }
41}