hermit/
init_cell.rs

1#![cfg_attr(
2	not(any(feature = "vsock", feature = "fuse", feature = "console")),
3	expect(dead_code)
4)]
5
6use hermit_sync::{OnceCell, SpinMutex};
7
8/// A cell for iteratively initializing a `OnceCell`.
9///
10/// This should be used as a stop-gap measure only.
11pub struct InitCell<T> {
12	init: SpinMutex<Option<T>>,
13	once: OnceCell<T>,
14}
15
16impl<T> InitCell<T> {
17	pub const fn new(val: T) -> Self {
18		Self {
19			init: SpinMutex::new(Some(val)),
20			once: OnceCell::new(),
21		}
22	}
23
24	pub fn with(&self, f: impl FnOnce(Option<&mut T>)) {
25		let mut guard = self.init.lock();
26		f((*guard).as_mut());
27	}
28
29	pub fn get(&self) -> Option<&T> {
30		self.once.get()
31	}
32
33	pub fn finalize(&self) -> &T {
34		self.once.get_or_init(|| self.init.lock().take().unwrap())
35	}
36}