hermit/
init_cell.rs

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