loom/rt/
lazy_static.rs

1use crate::rt::synchronize::Synchronize;
2use std::{any::Any, collections::HashMap};
3
4pub(crate) struct Set {
5    /// Registered statics.
6    statics: Option<HashMap<StaticKeyId, StaticValue>>,
7}
8
9#[derive(Eq, PartialEq, Hash, Copy, Clone)]
10pub(crate) struct StaticKeyId(usize);
11
12pub(crate) struct StaticValue {
13    pub(crate) sync: Synchronize,
14    v: Box<dyn Any>,
15}
16
17impl Set {
18    /// Create an empty statics set.
19    pub(crate) fn new() -> Set {
20        Set {
21            statics: Some(HashMap::new()),
22        }
23    }
24
25    pub(crate) fn reset(&mut self) {
26        assert!(
27            self.statics.is_none(),
28            "lazy_static was not dropped during execution"
29        );
30        self.statics = Some(HashMap::new());
31    }
32
33    pub(crate) fn drop(&mut self) -> HashMap<StaticKeyId, StaticValue> {
34        self.statics
35            .take()
36            .expect("lazy_statics were dropped twice in one execution")
37    }
38
39    pub(crate) fn get_static<T: 'static>(
40        &mut self,
41        key: &'static crate::lazy_static::Lazy<T>,
42    ) -> Option<&mut StaticValue> {
43        self.statics
44            .as_mut()
45            .expect("attempted to access lazy_static during shutdown")
46            .get_mut(&StaticKeyId::new(key))
47    }
48
49    pub(crate) fn init_static<T: 'static>(
50        &mut self,
51        key: &'static crate::lazy_static::Lazy<T>,
52        value: StaticValue,
53    ) -> &mut StaticValue {
54        let v = self
55            .statics
56            .as_mut()
57            .expect("attempted to access lazy_static during shutdown")
58            .entry(StaticKeyId::new(key));
59
60        if let std::collections::hash_map::Entry::Occupied(_) = v {
61            unreachable!("told to init static, but it was already init'd");
62        }
63
64        v.or_insert(value)
65    }
66}
67
68impl StaticKeyId {
69    fn new<T>(key: &'static crate::lazy_static::Lazy<T>) -> Self {
70        Self(key as *const _ as usize)
71    }
72}
73
74impl StaticValue {
75    pub(crate) fn new<T: 'static>(value: T) -> Self {
76        Self {
77            sync: Synchronize::new(),
78            v: Box::new(value),
79        }
80    }
81
82    pub(crate) fn get<T: 'static>(&self) -> &T {
83        self.v
84            .downcast_ref::<T>()
85            .expect("lazy value must downcast to expected type")
86    }
87}